[TUHS] Possible Assembly UNIX Kernel Images (s1-bits cunix/wunix)?

Briam Rodriguez via TUHS tuhs at tuhs.org
Sat Jan 17 08:11:11 AEST 2026


Hi Matt,

Saw your post about the v2src restoration project. I took a crack at 
disassembling the remaining binaries from the s2-bits tape - 
specifically the bin/ directory utilities.

I've got 26 commands disassembled and formatted to match your existing 
style conventions:

as, bas, cc, db, dc, ds, du, ed, fc, find, form, ld, maki, mv, nm, od, 
pr, roff, size, sort, stat, tap, tm, un, wc, who

They're ready as a patch file. Please find it attached. I tried creating 
a PR on gitlab but it wouldn't let me due to auth issues.

Happy to help with more disassembly work if there are other artifacts 
worth looking at.

-- Briam R.

On 1/16/26 5:06 PM, segaloco via TUHS wrote:
> Hello everyone, I've been picking back up on some of my V2/V3 era
> reverse engineering efforts, picking through stuff from the Dennis_Tapes
> archive, and I came across something I don't think I've seen discussed.
>
> On the s1 tape, which we've yoinked a lot of V3 userland sources from,
> there are files cunix and wunix.  Upon some disassembly and inspection,
> I believe these may be assembly UNIX kernels, although I haven't dug
> around too much to see what version they match most closely.  Here are
> some findings that support my suspicions:
>
> - Both files begin with a 407 magic number, making them V2 a.out
> binaries.
> - Both begin with a branch that jumps over a few things then calls a
> subroutine.  That subroutine matches "copyz" from u3.s in the scanned
> V1 kernel description from BTL.  Indeed this jump in that kernel is also
> to copyz.
>
> Of course, this is only the first few bits executed, but I would be
> surprised to find such a close match elsewhere in the system.  I do this
> sort of analysis on old video game code all the time, so I feel pretty
> confident in identifying these as possible assembly-era kernels.
>
> Anyone dug around in these before?  These should be PDP-11/20 kernels as
> I'm finding plenty of EAE references, just like the s2-bits V2 binaries.
> What I'm hoping to find here are bits that might indicate KS11 support,
> what with the recent chit chat about KS11 in the V2 kernel.
>
> - Matt G.
-------------- next part --------------
From 2498b221d611cd131f6be10610f55e21fb136c40 Mon Sep 17 00:00:00 2001
From: Briam Rodriguez <briamr at gmail.com>
Date: Fri, 16 Jan 2026 16:59:29 -0500
Subject: [PATCH] add disassembled bin/ commands from s2-bits

---
 cmd/as.s   |  817 ++++++++++++++++++++
 cmd/bas.s  | 2106 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 cmd/cc.s   |  871 ++++++++++++++++++++++
 cmd/db.s   |  793 ++++++++++++++++++++
 cmd/dc.s   |  508 +++++++++++++
 cmd/ds.s   |  267 +++++++
 cmd/du.s   |  187 +++++
 cmd/ed.s   |  437 +++++++++++
 cmd/fc.s   |  309 ++++++++
 cmd/find.s |  140 ++++
 cmd/form.s |  300 ++++++++
 cmd/ld.s   |  878 ++++++++++++++++++++++
 cmd/maki.s |   68 ++
 cmd/mv.s   |  157 ++++
 cmd/nm.s   |  211 ++++++
 cmd/od.s   |  112 +++
 cmd/pr.s   |  342 +++++++++
 cmd/roff.s | 1025 +++++++++++++++++++++++++
 cmd/size.s |  762 +++++++++++++++++++
 cmd/sort.s |  265 +++++++
 cmd/stat.s |  298 ++++++++
 cmd/tap.s  |  666 +++++++++++++++++
 cmd/tm.s   |  284 +++++++
 cmd/un.s   |   79 ++
 cmd/wc.s   |  180 +++++
 cmd/who.s  |  150 ++++
 26 files changed, 12212 insertions(+)
 create mode 100644 cmd/as.s
 create mode 100644 cmd/bas.s
 create mode 100644 cmd/cc.s
 create mode 100644 cmd/db.s
 create mode 100644 cmd/dc.s
 create mode 100644 cmd/ds.s
 create mode 100644 cmd/du.s
 create mode 100644 cmd/ed.s
 create mode 100644 cmd/fc.s
 create mode 100644 cmd/find.s
 create mode 100644 cmd/form.s
 create mode 100644 cmd/ld.s
 create mode 100644 cmd/maki.s
 create mode 100644 cmd/mv.s
 create mode 100644 cmd/nm.s
 create mode 100644 cmd/od.s
 create mode 100644 cmd/pr.s
 create mode 100644 cmd/roff.s
 create mode 100644 cmd/size.s
 create mode 100644 cmd/sort.s
 create mode 100644 cmd/stat.s
 create mode 100644 cmd/tap.s
 create mode 100644 cmd/tm.s
 create mode 100644 cmd/un.s
 create mode 100644 cmd/wc.s
 create mode 100644 cmd/who.s

diff --git a/cmd/as.s b/cmd/as.s
new file mode 100644
index 0000000..658a14f
--- /dev/null
+++ b/cmd/as.s
@@ -0,0 +1,817 @@
+/ as -- assembler pass 1
+
+	br	start
+tsize:	mov	0(sp),(sp)
+	0
+	0
+	0
+	0
+symend:	1
+
+/ start of program
+start:
+	jmp	main
+
+/ error handling
+error:
+	jsr	pc,pass1
+	movb	errflg,r0
+	sys	creat; tmpf1; 1000
+	movb	errflg,r0
+	sys	creat; tmpf2; 0
+	movb	passno,r0
+	tstb	dotflg
+	bne	1f
+	jsr	r5,errstr
+		<-e\n\0>; .even
+	inc	(r1)
+	bic	$1,(r1)+
+	inc	(r1)
+	bic	$1,(r1)+
+	inc	(r1)
+	bic	$1,(r1)+
+	mov	r0,r1
+	sys	creat; tmpf1; 1000
+	0
+	rtt
+
+/ setup temporary file name
+tmpset:
+	mov	r4,-(sp)
+	mov	(r5)+,r4
+	mov	r4,0f
+	clr	r0
+1:
+	tstb	(r4)+
+	beq	1f
+	inc	r0
+	br	1b
+1:
+	mov	r0,0f+2
+	mov	$1,r0
+	sys	creat; 0:..; 0
+
+/ return from tmpset
+	mov	r5,0f
+	mov	$1,r0
+	sys	creat; 0:..; rtt
+
+1:
+	incb	11.(r4)
+	cmpb	11.(r4),$'z
+	blos	1b
+	mov	0b,0f
+	jsr	r5,tmpset; 0:..; clr	@syms+2
+	incb	dotflg
+	mov	r0,-(sp)
+	mov	r1,-(sp)
+	mov	(r5)+,r0
+	mov	@argptr,0f
+	beq	1f
+	clr	@argptr
+	mov	r0,-(sp)
+	jsr	r5,tmpset; 0:..; rtt
+1:
+	mov	(sp)+,r0
+	mov	argptr,0f
+	movb	r0,0f+48.
+	mov	$tmpstr,r0
+	mov	$-4,r1
+	clr	hession
+	mov	$12.,hession+2
+	add	$48.,hession
+	movb	hession,-(r0)
+	inc	r1
+	bne	1b
+	mov	$1,r0
+	sys	creat; tmpstr; 7
+	mov	(sp)+,r1
+	mov	(sp)+,r0
+	rts	r5
+
+tmpstr:	<  xxxx\n\0>
+	.even
+
+/ range check
+rangck:
+	cmp	r0,$9.
+	bhi	1f
+	rts	pc
+1:
+	jsr	r5,errstr; <r\0>
+	.even
+
+clrone:
+	clr	r0
+	rts	pc
+
+/ skip to newline/semicolon/eof
+skip:
+	cmp	r4,$'\n
+	beq	1f
+	cmp	r4,$';
+	beq	1f
+	cmp	r4,$4
+	beq	1f
+	rts	pc
+1:
+	add	$2,(sp)
+	rts	pc
+
+/ symbol table routines
+lookup:
+	mov	r2,-(sp)
+	mov	r3,-(sp)
+	mov	$2,r5
+	mov	$symtab,r2
+	clr	-(sp)
+	jsr	pc,gethash
+	mov	r3,hession
+	mov	$40.,hession+2
+	jsr	pc,gethash
+	add	r3,hession
+	mov	$40.,hession+2
+	jsr	pc,gethash
+	add	hession,r3
+	add	r3,(sp)
+	mov	r3,(r2)+
+	dec	r5
+	bne	1b
+	jsr	pc,gethash
+	mov	r3,hession
+	add	r3,(sp)
+	mov	$12.,hession+4
+	mov	hession,(r2)
+	jsr	pc,gethash
+	tst	r3
+	bne	1b
+	mov	(sp)+,hession
+	clr	hession+2
+	mov	$1000.,hession+8
+	mov	hession,r0
+	asl	r0
+	add	$symtab,r0
+	cmp	r0,$symtab
+	bhi	1f
+	mov	$symend,r0
+1:
+	mov	$symtab,r2
+	mov	-(r0),r4
+	beq	1f
+	cmp	(r2)+,(r4)+
+	bne	1b
+	cmp	(r2)+,(r4)+
+	bne	1b
+	cmpb	1(r4),1(r2)
+	bne	1b
+	br	2f
+1:
+	mov	hession+4,r4
+	mov	r4,(r0)
+	mov	r4,-(sp)
+	add	$16.,r4
+	cmp	r4,0f
+	blos	1f
+	add	$512.,0f
+	sys	intr; symtab+2
+	mov	(sp)+,r4
+	mov	(r2)+,(r4)+
+	mov	(r2)+,(r4)+
+	mov	(r2)+,(r4)+
+	clr	(r4)+
+	mov	r4,hession+4
+	sub	$4,r4
+2:
+	mov	r4,-(sp)
+	sub	$symhash,r4
+	asr	r4
+	jsr	pc,putw
+	mov	(sp)+,r4
+	mov	(sp)+,r3
+	mov	(sp)+,r2
+	tst	(sp)+
+	rts	pc
+
+/ get hash value
+gethash:
+	jsr	pc,rch
+	movb	spts(r0),r3
+	ble	1f
+	rts	pc
+1:
+	movb	r0,savec
+	clr	r3
+	rts	pc
+
+/ read character
+rch:
+	movb	savec,r0
+	beq	1f
+	clrb	savec
+	rts	pc
+1:
+	dec	ibufcnt
+	blt	fillbuf
+	movb	@ibufp,r0
+	inc	ibufp
+	bic	$177600,r0
+	bne	1b
+	rts	pc
+
+/ fill input buffer
+fillbuf:
+	movb	infile,r0
+	beq	nextfile
+	sys	read; ibuf; 512.
+	bes	1f
+	tst	r0
+	beq	1f
+	mov	r0,ibufcnt
+	mov	$ibuf,ibufp
+	br	rch
+1:
+	movb	infile,r0
+	clrb	infile
+	sys	creat; tmpf1; 1000
+
+nextfile:
+	decb	fcount
+	bgt	1f
+	mov	$4,r0
+	rts	pc
+1:
+	tst	pass
+	beq	1f
+	jsr	r5,errstr; <i\0>
+	.even
+	jmp	error+8
+1:
+	mov	argptr,r0
+	tst	(r0)+
+	mov	(r0),0f
+	mov	r0,argptr
+	incb	fnumba
+	sys	open; 0:..; 0
+
+	bec	1f
+	clr	@0b
+	jmp	error+8
+1:
+	movb	r0,infile
+	mov	$1,line
+	mov	r4,-(sp)
+	mov	r1,-(sp)
+	mov	$5,r4
+	jsr	pc,putw
+	mov	@argptr,r1
+	movb	(r1)+,r4
+	beq	1f
+	jsr	pc,putw
+	br	1b
+1:
+	mov	$-1,r4
+	jsr	pc,putw
+	mov	(sp)+,r1
+	mov	(sp)+,r4
+	br	rch
+
+/ get token
+readop:
+	mov	tok,r4
+	beq	1f
+	clr	tok
+	rts	pc
+1:
+	jsr	pc,1f
+	jsr	pc,putw
+	rts	pc
+
+1:
+	jsr	pc,rch
+	mov	r0,r4
+	movb	spts(r0),r1
+	bgt	1f
+	jmp	@dtbl(r1)
+
+/ dispatch table for token types
+dtbl:
+	dtbl+2
+	aletter
+	anumber
+	asquote
+	adquote
+	dtbl+2
+	adoll
+	aslash
+	aless
+	dtbl+2
+	aesc
+
+/ escape sequences
+aesc:
+	jsr	r5,errstr; <//=<\0>; .even
+
+/ operator table entry
+optbl:
+	<+-*/%&|>>>!<^^~\0>
+	.even
+
+aslash:
+	jsr	pc,rch
+	mov	r0,r4
+	cmp	r0,$4
+	beq	1f
+	cmp	r0,$'\n
+	bne	aslash
+1:
+	rts	pc
+
+/ letter - identifier
+aletter:
+	movb	r0,savec
+	cmp	r1,$32.
+	ble	1f
+	cmp	r1,$45.
+	blt	1f
+	jmp	lookup
+1:
+	jsr	pc,readnum
+	br	2f
+
+/ number
+anumber:
+	jsr	pc,rch
+	mov	r0,r4
+	movb	spts(r0),r1
+	bgt	1f
+	cmp	r0,$'b
+	beq	bref
+	cmp	r0,$'f
+	beq	fref
+	cmp	r0,$'.
+	bne	1f
+	mov	hession,r1
+	clr	r0
+1:
+	movb	r0,savec
+	mov	r1,r0
+	mov	(sp)+,r3
+	mov	(sp)+,r2
+	rts	pc
+
+/ backref (Nb)
+bref:
+	mov	r0,r3
+	mov	hession,r0
+	jsr	pc,rangck
+	add	$'a,r0
+	cmp	r3,$'b
+	beq	1f
+	add	$12.,r0
+1:
+	mov	r0,r4
+	mov	(sp)+,r3
+	mov	(sp)+,r2
+	add	$2,(sp)
+	rts	pc
+
+/ forward ref (Nf)
+fref:
+	jsr	pc,rch
+	mov	r0,r4
+	cmp	r0,$4
+	beq	1f
+	cmp	r0,$'\n
+	bne	fref
+1:
+	rts	pc
+
+/ dollar sign (immediate)
+adoll:
+	jsr	r5,errstr; <g\0>
+	.even
+
+/ less-than (string)
+aless:
+	mov	$'<,r4
+	jsr	pc,putw
+	clr	val
+	jsr	pc,getch
+	tst	r1
+	bne	1f
+	mov	r0,r4
+	bis	$400,r4
+	jsr	pc,putw
+	inc	val
+	br	1b
+1:
+	mov	$-1,r4
+	jsr	pc,putw
+	mov	$'<,r4
+	tst	(sp)+
+	rts	pc
+
+/ get string char
+getch:
+	jsr	pc,rch
+	cmp	r0,$4
+	beq	1f
+	cmp	r0,$'\n
+	beq	1f
+	clr	r1
+	cmp	r0,$'\\
+	bne	2f
+	jsr	pc,rch
+	mov	$esctbl,r2
+1:
+	cmpb	(r2)+,r0
+	beq	3f
+	tstb	(r2)+
+	bpl	1b
+	rts	pc
+3:
+	movb	(r2)+,r0
+	clr	r1
+	rts	pc
+2:
+	cmp	r0,$'>
+	bne	4f
+	inc	r1
+4:
+	rts	pc
+
+esctbl:
+	'n; 12
+	'r; 15
+	't; 11
+	'b; 10
+	'0; 0
+	-1
+
+/ read number
+readnum:
+	mov	r2,-(sp)
+	mov	r3,-(sp)
+	clr	r1
+	clr	hession
+	jsr	pc,rch
+	jsr	r5,rangck
+	$'0
+	$'9
+	br	1f
+
+1:
+	sub	$'0,r0
+	mov	$12.,hession+2
+	add	r0,hession
+	asl	r1
+	asl	r1
+	asl	r1
+	add	r0,r1
+	br	readnum+6
+
+/ expression parser
+expr:
+	cmp	r0,$'b
+	beq	bref
+	cmp	r0,$'f
+	beq	fref
+	cmp	r0,$'.
+	bne	1f
+	mov	hession,r1
+	clr	r0
+1:
+	movb	r0,savec
+	mov	r1,r0
+	mov	(sp)+,r3
+	mov	(sp)+,r2
+	rts	pc
+
+/ expression with operators
+exprop:
+	jsr	pc,rch
+	mov	r0,r4
+	cmp	r0,$'<
+	bne	1f
+	jmp	aless
+1:
+	jsr	pc,oprand
+	add	$2,dotval
+	rts	pc
+
+/ addressing mode parsing
+opclass:
+	mov	r0,-(sp)
+	jsr	pc,readop
+	mov	(sp)+,r0
+	asl	r0
+	jmp	@clstbl(r0)
+
+clstbl:
+	sngop
+	dblop
+	sngop
+	dblop
+	dblop
+	sngop
+	sngop
+	sngop
+	sngop
+	sngop
+	sngop
+	branch
+	branch
+	extjsr
+	extsob
+	branch
+	branch
+	branch
+	branch
+	branch
+	branch
+	branch
+	branch
+	sngop
+	fltop
+	fltop
+	fltop
+	fltop
+	sngop
+	branch
+
+/ single operand instruction
+sngop:
+	jsr	pc,oprand
+	cmp	r4,$',
+	bne	1f
+	jsr	pc,readop
+	jsr	pc,oprand
+	add	$2,dotval
+1:
+	rts	pc
+
+/ double operand instruction
+dblop:
+	jsr	pc,oprand
+	jsr	pc,readop
+	jsr	pc,oprand
+	add	$2,dotval
+	cmp	r4,$',
+	bne	1f
+	jsr	pc,readop
+	br	dblop+4
+1:
+	rts	pc
+
+/ branch instruction
+branch:
+	jsr	pc,oprand
+	inc	dotval
+	bic	$1,dotval
+	rts	pc
+
+/ floating point operation
+fltop:
+	jsr	pc,oprand
+	tst	r3
+	bne	1f
+	jsr	r5,errstr; <U\0>
+	.even
+1:
+	tst	r2
+	bne	1f
+	inc	pass
+1:
+	rts	pc
+
+/ register expression
+regxpr:
+	cmp	r4,$200
+	bcs	1f
+	bisb	$40,(r4)
+	jsr	pc,readop
+	cmp	r4,$',
+	bne	1f
+	jsr	pc,readop
+	br	regxpr
+1:
+	rts	pc
+
+/ segment switching
+segswt:
+	mov	dotval,r1
+	asl	r1
+	mov	dotval,locseg(r1)
+	mov	absdat(r0),dotval
+	asr	r0
+	sub	$23.,r0
+	mov	r0,dotrel
+	rts	pc
+
+/ operand parsing
+oprand:
+	cmp	r4,$200
+	bcs	1f
+	mov	$40,(r4)
+	jsr	pc,readop
+	cmp	r4,$',
+	bne	1f
+	jsr	pc,readop
+	jsr	pc,oprand
+	rts	pc
+1:
+	jsr	r5,errstr; <x\0>
+	.even
+	jmp	error+8
+
+/ extended JSR
+extjsr:
+	cmp	r4,$',
+	beq	1f
+	jsr	pc,oprand
+	rts	pc
+1:
+	jsr	pc,readop
+	jsr	pc,oprand
+	rts	pc
+
+/ extended SOB
+extsob:
+	jsr	pc,oprand
+	inc	dotval
+	bic	$1,dotval
+	rts	pc
+
+/ pass 1 driver
+pass1:
+	jsr	pc,pass1dr
+	rts	pc
+
+pass1dr:
+	jsr	pc,readop
+	cmp	r4,$'\n
+	beq	1f
+	cmp	r4,$';
+	beq	1f
+	cmp	r4,$4
+	bne	pass1dr
+1:
+	jmp	pass1+8
+
+/ put word to output
+putw:
+	tst	pass
+	bne	1f
+	cmp	r4,$'\n
+	beq	1f
+	movb	r4, at bufp
+	inc	bufp
+	cmp	bufp,$bufend
+	bcs	1f
+	mov	$buf,bufp
+	movb	errflg,r0
+	sys	creat; tmpf1; 1000
+
+1:
+	rts	pc
+
+/ error message output
+errstr:
+	mov	r4,-(sp)
+	mov	(r5)+,r4
+	mov	r4,0f
+	mov	$tmpstr,r0
+	mov	$1,r0
+	sys	write; 0:..; 4
+
+	mov	(sp)+,r4
+	br	skip
+
+/ main entry point
+main:
+	sys	intr; error
+	bic	r1,-(sp)
+	mov	sp,r5
+	mov	(r5)+,r0
+	cmpb	@2(r5),$'-
+	bne	1f
+	tst	(r5)+
+	dec	r0
+	br	main+16.
+1:
+	clr	oteflag
+	movb	r0,fcount
+	mov	r5,argptr
+	jsr	r5,tmpset
+		<a.out\0>; .even
+	movb	r0,errflg
+	jsr	r5,tmpset
+		<atm1a\0>; .even
+	movb	r0,passno
+	jsr	pc,setup
+	mov	$1,r0
+	sys	creat; tmpf1; 2
+
+	jmp	error+8
+
+/ setup symbol table
+setup:
+	mov	$symtbl,r1
+	mov	$symtab,r0
+1:
+	mov	(r1)+,(r0)+
+	beq	1f
+	mov	(r1)+,(r0)+
+	mov	(r1)+,r2
+	bic	$37,r2
+	mov	r2,(r0)+
+	mov	r1,-(sp)
+	jsr	pc,hshlkp
+	mov	(sp)+,r1
+	mov	r1,(r0)
+	sub	$6,(r0)
+	tst	(r1)+
+	br	1b
+1:
+	rts	pc
+
+/ hash lookup
+hshlkp:
+	mov	topstk,r1
+	add	topstk+2,r1
+	add	topstk+4,r1
+	mov	r1,hession
+	clr	hession+2
+	mov	$1000.,hession+8
+	mov	hession,r0
+	asl	r0
+	add	$symtab,r0
+	cmp	r0,$symtab
+	bhi	1f
+	mov	$symend,r0
+1:
+	mov	-(r0),r2
+	beq	1f
+	mov	$symtab,r3
+	cmp	(r2)+,(r3)+
+	bne	1b
+	cmp	(r2)+,(r3)+
+	bne	1b
+	mov	(r2)+,r1
+	bic	$37,r1
+	cmp	r1,(r3)+
+	bne	1b
+1:
+	rts	pc
+
+/ instruction table (partial)
+/ format: name; opcode; type
+symtbl:
+.=.+2
+locseg:	.=.+24.
+absdat:	.=.+24.
+/ EAE registers
+div = 177300
+ac  = 177302
+mq  = 177304
+mul = 177306
+sc  = 177310
+sr  = 177311
+nor = 177312
+lsh = 177314
+ash = 177316
+
+/ temp file names
+tmpf1:	</etc/as2-\0>
+tmpf2:	</tmp/atm1a\0>
+tmpf3:	</tmp/atm2a\0>
+
+/ data area
+.bss
+savec:	.=.+1
+dotflg:	.=.+1
+fnumba:	.=.+1
+errflg:	.=.+1
+passno:	.=.+1
+infile:	.=.+1
+fcount:	.=.+1
+	.even
+line:	.=.+2
+pass:	.=.+2
+tok:	.=.+2
+val:	.=.+2
+dotval:	.=.+2
+dotrel:	.=.+2
+oteflag: .=.+2
+argptr:	.=.+2
+ibufcnt: .=.+2
+ibufp:	.=.+2
+bufp:	.=.+2
+topstk:	.=.+6
+hession: .=.+12.
+ibuf:	.=.+512.
+buf:	.=.+512.
+bufend:
+symhash: .=.+2048.
+symtab:	.=.+4096.
+syms:
diff --git a/cmd/bas.s b/cmd/bas.s
new file mode 100644
index 0000000..a96409e
--- /dev/null
+++ b/cmd/bas.s
@@ -0,0 +1,2106 @@
+/ bas -- BASIC interpreter
+
+	br	start
+	mov	@(r4)+,-(r2)
+	0
+	0
+
+	bgt	1f
+	0
+
+start:
+	jmp	init
+
+/ return from FPU trap
+fpret:
+	rts	r5
+
+/ save state for FPU trap handler
+fptrap:
+	mov	(sp)+,fppc
+	mov	(sp)+,fpps
+	mov	r0,fpr0
+	mov	$fpregs,r0
+	mov	r1,(r0)+
+	mov	r2,(r0)+
+	mov	r3,(r0)+
+	mov	r4,(r0)+
+	mov	r5,(r0)+
+	mov	sp,(r0)+
+	sub	$10,sp
+	mov	(r0),r5
+	clr	fperr
+	bic	$100000,fpflags
+	mov	-(r5),r5
+	mov	r5,r4
+	bic	$7777,r4
+	cmp	r4,$170000
+	bne	fpbad
+	bic	$170000,r5
+	mov	r5,r4
+	bit	$7000,r4
+	bne	1f
+	bit	$700,r4
+	bne	2f
+	cmp	r4,$12
+	bhi	fpbad
+	asl	r4
+	jmp	@fptbl(r4)
+
+fptbl:
+	fpop0; fpop1
+	fpop2; fpop3; fpop3
+	fpop3; fpop3; fpop3
+	fpop4; fpop5
+
+2:
+	cmp	r5,$400
+	bge	3f
+	jsr	r1,fpaddr
+	.+4
+	.+2
+	br	4f
+
+3:
+	jsr	r1,fpaddr
+	.+4
+	.+2
+4:
+	mov	r3,r5
+	asl	r4
+	asl	r4
+	clrb	r4
+	swab	r4
+	asl	r4
+	jsr	pc, at fptbl2(r4)
+	br	fpdone
+
+fptbl2:
+	fpop3; fpld
+	fpst; fpop3; fpneg
+	fpabs; fpclr; fpadd
+	fpsub; fpmul; fpdiv
+	fpcmp; fpmod; fpldx
+	fpstx; fpint; fpldc
+	fpldi; fpstc; fpsti
+
+1:
+	cmp	r5,$5000
+	blt	fpop6
+	mov	r5,r2
+	clrb	r2
+	cmp	r2,$6400
+	blt	1f
+	sub	$1400,r2
+1:
+	cmp	r2,$5000
+	bne	2f
+	jsr	r1,fpaddr
+	.+4
+	.+2
+	br	3f
+
+2:
+	cmp	r2,$5400
+	bne	4f
+	jsr	r1,fpaddr
+	.+6; .+4
+	br	3f
+
+4:
+	jsr	r1,fpaddr
+	.+4
+	.+2
+3:
+	jsr	pc,getfreg
+	mov	r2,r5
+	clrb	r4
+	swab	r4
+	asl	r4
+	jsr	pc, at fptbl3(r4)
+	br	fpdone
+
+fptbl3:
+	fpop3; fpop3
+	fpmulf; fpmuld
+	fpaddf; fpaddd
+	fpldf; fpstf
+	fpsubf; fpsubd
+	fpdivf; fpdivd
+	fpcmpf; fpcmpd
+	fpmodf; fpmodd
+	fpldfx; fpstfx
+	fpaddx; fpsubx
+	fpldcx; fpstcx
+
+fpbad:
+	inc	fperr
+	br	fpret2
+
+fpop0:
+	mov	fpflags,r0
+	bic	$177760,r0
+	mov	r0,fpps
+	br	fpret2
+
+fpop1:
+	bic	$200,fpflags
+	br	fpret2
+
+fpop2:
+	bis	$200,fpflags
+	br	fpret2
+
+fpop3:
+	bic	$100,fpflags
+	br	fpret2
+
+fpop4:
+	bis	$100,fpflags
+	br	fpret2
+
+fpdone:
+	mov	$fpregs+8.,r0
+	bic	$17,(r0)
+	tst	(r5)
+	bpl	1f
+	bis	$10,(r0)
+	br	fpret2
+1:
+	bne	fpret2
+	bis	$4,(r0)
+fpret2:
+	mov	$fpregs,r0
+	mov	(r0)+,r1
+	mov	(r0)+,r2
+	mov	(r0)+,r3
+	mov	(r0)+,r4
+	mov	(r0)+,r5
+	mov	(r0)+,sp
+	mov	fpr0,r0
+	mov	fpps,-(sp)
+	mov	fppc,-(sp)
+	tst	fperr
+	bne	1f
+	rti
+1:
+	mov	@$14,pc
+
+/ get FPU register address
+getfreg:
+	mov	r5,r3
+	bic	$177770,r3
+	asl	r3
+	add	$fpregs+8.,r3
+	mov	r5,r0
+	bic	$177707,r0
+	asr	r0
+	asr	r0
+	jmp	@fprtbl(r0)
+
+fprtbl:
+	1f; 2f; 3f; 4f
+	5f; 6f; 7f; 8f
+
+1:
+	jmp	(r1)+
+
+2:
+	sub	$fpregs+8.,r3
+	cmp	r3,$14
+	bcc	fpbad
+	asl	r3
+	asl	r3
+	add	$fpac,r3
+	tst	(r1)+
+	rts	r1
+
+3:
+	bit	$100,fpflags
+	bne	fpbad
+	cmp	r3,$fpregs+12.
+	bcc	fpbad
+	tst	(r1)+
+	rts	r1
+
+4:
+	cmp	r3,$fpregs+14.
+	beq	fpbad
+	mov	(r3),r3
+	br	fpchk
+
+5:
+	mov	(r3),-(sp)
+	jsr	pc, at 2(r1)
+	add	r0,(r3)
+	mov	(sp)+,r3
+	br	fpchk
+
+6:
+	mov	@0(r3),-(sp)
+	add	$2,(r3)
+	mov	(sp)+,r3
+	br	fpchk
+
+7:
+	cmp	r3,$fpregs+14.
+	beq	fpbad
+	jsr	pc, at 2(r1)
+	sub	r0,(r3)
+	mov	(r3),r3
+	br	fpchk
+
+8:
+	cmp	r3,$fpregs+14.
+	beq	fpbad
+	sub	$2,(r3)
+	mov	@0(r3),r3
+	br	fpchk
+
+fpop5:
+	mov	@fppc,-(sp)
+	add	$2,fppc
+	add	(r3),(sp)
+	mov	(sp)+,r3
+	br	fpchk
+
+fpop6:
+	jsr	r1,fpop5
+	0
+	0
+	mov	(r3),r3
+	br	fpchk+2
+
+fpchk:
+	bit	$1,r3
+	bne	fpbad
+	cmp	r3,$40010
+	bcs	fpbad
+	cmp	r3,$57770
+	bcc	fpbad
+	add	$4,r1
+	rts	r1
+
+/ load float to internal format
+fpld:
+	mov	$fpwork,r0
+	jsr	pc,1f
+	mov	r3,r2
+	mov	$fpwork2,r0
+1:
+	clr	(r0)
+	mov	(r2)+,r1
+	mov	r1,-(sp)
+	beq	2f
+	blt	3f
+	inc	(r0)+
+	br	4f
+3:
+	dec	(r0)+
+4:
+	bic	$177600,r1
+	bis	$200,r1
+	br	5f
+2:
+	clr	(r0)+
+5:
+	mov	r1,(r0)+
+	mov	(r2)+,(r0)+
+	bit	$200,fpflags
+	beq	1f
+	mov	(r2)+,(r0)+
+	mov	(r2)+,(r0)+
+	br	2f
+1:
+	clr	(r0)+
+	clr	(r0)+
+2:
+	mov	(sp)+,r1
+	asl	r1
+	clrb	r1
+	swab	r1
+	sub	$200,r1
+	mov	r1,(r0)+
+	rts	pc
+
+/ store from internal to external format
+fpst:
+	mov	$fpwork+2,r0
+	mov	(r0)+,r1
+	mov	r1,-(sp)
+	mov	(r0)+,r2
+	bis	r2,(sp)
+	mov	(r0)+,r3
+	bis	r3,(sp)
+	mov	(r0)+,r4
+	bis	r4,(sp)+
+	bne	1f
+	clr	fpwork
+	rts	pc
+1:
+	bit	$177400,r1
+	beq	2f
+	clc
+	ror	r1
+	ror	r2
+	ror	r3
+	ror	r4
+	inc	(r0)
+	br	1b
+2:
+	bit	$200,r1
+	bne	1f
+	asl	r4
+	rol	r3
+	rol	r2
+	rol	r1
+	dec	(r0)
+	br	2b
+1:
+	mov	r4,-(r0)
+	mov	r3,-(r0)
+	mov	r2,-(r0)
+	mov	r1,-(r0)
+	rts	pc
+
+/ copy float r3 -> r2
+fpcpy32:
+	mov	(r3)+,(r2)+
+	mov	(r3)+,(r2)+
+	bit	$200,fpflags
+	beq	1f
+	mov	(r3)+,(r2)+
+	mov	(r3)+,(r2)+
+	rts	pc
+1:
+	clr	(r2)+
+	clr	(r2)+
+	rts	pc
+
+/ copy float r2 -> r3
+fpcpy23:
+	mov	(r2)+,(r3)+
+	mov	(r2)+,(r3)+
+	bit	$200,fpflags
+	beq	1f
+	mov	(r2)+,(r3)+
+	mov	(r2)+,(r3)+
+1:
+	rts	pc
+
+/ clear float at r3
+fpclr:
+	clr	(r3)+
+	clr	(r3)+
+	bit	$200,fpflags
+	beq	1f
+	clr	(r3)+
+	clr	(r3)+
+1:
+	rts	pc
+
+/ negate float at r3
+fpneg:
+	tst	(r3)
+	beq	1f
+	add	$100000,(r3)
+1:
+	rts	pc
+
+/ absolute value at r3
+fpabs:
+	bic	$100000,(r3)
+	rts	pc
+
+/ nop
+fpnop:
+	rts	pc
+
+/ compare floats
+fpcmp:
+	mov	$fpwork+2,r5
+	cmp	(r2)+,(r3)+
+	bgt	1f
+	blt	2f
+	cmp	(r2)+,(r3)+
+	bne	3f
+	bit	$200,fpflags
+	beq	4f
+	cmp	(r2)+,(r3)+
+	bne	3f
+	cmp	(r2)+,(r3)+
+	beq	4f
+3:
+	bhi	1f
+2:
+	mov	$1,(r5)
+	rts	pc
+1:
+	mov	$-1,(r5)
+	rts	pc
+4:
+	clr	(r5)
+	rts	pc
+
+/ copy r3 -> r2 (single precision mode)
+fpldf:
+	mov	(r3)+,(r2)+
+	mov	(r3)+,(r2)+
+	bit	$200,fpflags
+	bne	1f
+	mov	(r3)+,(r2)+
+	mov	(r3)+,(r2)+
+	rts	pc
+1:
+	clr	(r2)+
+	clr	(r2)+
+	rts	pc
+
+/ copy r2 -> r3 (single precision mode)
+fpstf:
+	mov	(r2)+,(r3)+
+	mov	(r2)+,(r3)+
+	bit	$200,fpflags
+	bne	1f
+	clr	(r3)+
+	clr	(r3)+
+1:
+	rts	pc
+
+/ load integer to float
+fpldi:
+	mov	$fpwork,r0
+	mov	$1,(r0)+
+	mov	(r3)+,(r0)+
+	bit	$100,fpflags
+	beq	1f
+	mov	(r3)+,(r0)+
+	clr	(r0)+
+	clr	(r0)+
+	mov	$30,(r0)+
+	jmp	fpst+4
+1:
+	clr	(r0)+
+	clr	(r0)+
+	clr	(r0)+
+	mov	$10,(r0)
+	jmp	fpst+4
+
+/ store float to integer
+fpsti:
+	mov	r3,r5
+	mov	$fpwork,r0
+	jsr	pc,fpld+4
+	mov	$fpwork+2,r0
+	mov	(r0)+,r1
+	mov	(r0)+,r2
+	mov	(r0)+,r3
+	mov	fpwork2+8.,r0
+	cmp	r0,$50
+	bge	1f
+	clc
+	ror	r1
+	ror	r2
+	ror	r3
+	inc	r0
+	br	.-14
+1:
+	bgt	2f
+	tst	r1
+	bne	2f
+	bit	$100,fpflags
+	beq	3f
+	tst	fpwork
+	bge	4f
+	neg	r3
+	adc	r2
+	bcs	4f
+	neg	r2
+4:
+	mov	r2,(r5)
+	mov	r3,2(r5)
+	rts	pc
+3:
+	tst	r2
+	bne	2f
+	tst	fpwork
+	bge	5f
+	neg	r3
+5:
+	mov	r3,(r5)
+	rts	pc
+2:
+	bis	$1,fpflags
+	jmp	fpret2
+
+/ floating point add setup
+fpadd:
+	mov	$fpwork,r0
+	jsr	pc,fpld+4
+	mov	(r3),fpwork2+8.
+	jsr	pc,fpadd2
+	jmp	fpdone
+
+/ floating point subtract
+fpsub:
+	mov	$fpwork,r0
+	jsr	pc,fpld+4
+	mov	fpwork2+8.,(r3)
+	mov	r3,r5
+	jmp	fpdone
+
+/ modify status flags
+fpmod:
+	mov	(r3),fpflags
+	jmp	fpret2
+
+/ read status flags
+fpmodx:
+	mov	fpflags,(r3)
+	jmp	fpret2
+
+/ add internal format numbers
+fpaddf:
+	jsr	pc,fpld
+	br	fpadd3
+
+fpaddd:
+	jsr	pc,fpld
+	neg	fpwork2+8.
+fpadd3:
+	tst	fpwork2+8.
+	beq	fpadd2
+	tst	fpwork
+	beq	1f
+	mov	fpwork2+8.,r1
+	sub	fpwork2+10.,r1
+	blt	2f
+	beq	3f
+	cmp	r1,$70
+	bge	fpadd2
+	mov	$fpwork2+4,r0
+	br	4f
+2:
+	neg	r1
+	cmp	r1,$70
+	bge	1f
+	mov	$fpwork+2,r0
+4:
+	mov	r1,-(sp)
+	mov	(r0)+,r1
+	mov	(r0)+,r2
+	mov	(r0)+,r3
+	mov	(r0)+,r4
+	add	(sp),(r0)
+	clc
+	ror	r1
+	ror	r2
+	ror	r3
+	ror	r4
+	dec	(sp)
+	bgt	.-14
+	mov	r4,-(r0)
+	mov	r3,-(r0)
+	mov	r2,-(r0)
+	mov	r1,-(r0)
+	tst	(sp)+
+3:
+	mov	$fpwork2+6,r1
+	mov	$fpwork2+10.,r2
+	mov	$4,r0
+	cmp	fpwork,fpwork2+8.
+	bne	5f
+	clc
+	adc	-(r1)
+	bcs	6f
+	add	-(r2),(r1)
+	dec	r0
+	bne	.-10
+	br	7f
+6:
+	add	-(r2),(r1)
+	sec
+	br	.-10
+
+	br	7f
+
+5:
+	clc
+	sbc	-(r1)
+	bcs	8f
+	sub	-(r2),(r1)
+	dec	r0
+	bne	.-10
+	br	9f
+8:
+	sub	-(r2),(r1)
+	sec
+	br	.-10
+
+fpst2:
+	mov	$fpwork+2,r1
+9:
+	tst	(r1)
+	bge	1f
+	mov	$fpwork2+6,r1
+	mov	$4,r0
+	clc
+	adc	-(r1)
+	bcs	2f
+	neg	(r1)
+2:
+	dec	r0
+	bne	.-10
+	neg	-(r1)
+1:
+	jsr	pc,fpst
+	br	fpadd2
+
+7:
+	mov	$fpwork2+4,r1
+	mov	$fpwork,r2
+	mov	$6,r0
+1:
+	mov	(r1)+,(r2)+
+	dec	r0
+	bne	1b
+fpadd2:
+	mov	r5,r2
+	mov	$fpwork,r0
+	tst	(r0)
+	beq	2f
+	mov	fpwork2+8.,r1
+	cmp	r1,$177
+	ble	1f
+	jsr	pc,fpexp
+	sub	$200,r1
+1:
+	cmp	r1,$-177
+	bge	1f
+	jsr	pc,fpexp
+	add	$200,r1
+1:
+	add	$200,r1
+	swab	r1
+	clc
+	ror	r1
+	tst	(r0)+
+	bge	1f
+	bis	$100000,r1
+1:
+	bic	$177600,(r0)
+	bis	(r0)+,r1
+	mov	r1,(r2)+
+	mov	(r0)+,(r2)+
+	bit	$200,fpflags
+	beq	1f
+	mov	(r0)+,(r2)+
+	mov	(r0)+,(r2)+
+1:
+	rts	pc
+
+2:
+	clr	(r2)+
+	clr	(r2)+
+	bit	$200,fpflags
+	beq	1f
+	clr	(r2)+
+	clr	(r2)+
+1:
+	rts	pc
+
+fpexp:
+	bis	$2,fpflags
+	jmp	fpret2
+
+/ multiply
+fpmulf:
+	jsr	pc,fpld
+	br	fpmul2
+
+fpmulr:
+	jsr	pc,fpld
+	jsr	pc,fpst
+	mov	$fpwork,r0
+	mov	$fpwork2+4,r1
+	mov	$6,r2
+1:
+	mov	(r0)+,(r1)+
+	dec	r2
+	bne	1b
+	clr	r0
+	cmp	r0,fpwork2+8.
+	bge	1f
+	bic	r1,fpwork+2(r2)
+	br	2f
+1:
+	bic	r1,fpwork2+4(r2)
+2:
+	inc	r0
+	clc
+	ror	r1
+	bne	1b
+	mov	$100000,r1
+	add	$2,r2
+	cmp	r2,$10
+	blt	1b
+	jsr	pc,fpst
+	jsr	pc,fpadd2
+	cmp	r5,$fpac
+	beq	1f
+	cmp	r5,$fpac+10.
+	beq	1f
+	bit	$200,fpwork2+4
+	bne	2f
+	clr	fpwork2+8.
+2:
+	add	$10,r5
+	jsr	pc,1f
+	sub	$10,r5
+1:
+	rts	pc
+
+/ divide
+fpdiv:
+	jsr	pc,fpld
+	add	fpwork2+10.,fpwork2+8.
+	dec	fpwork2+8.
+	jsr	pc,fpsgn
+	mov	r5,-(sp)
+	mov	$fpwork,r0
+	mov	(r0),r1
+	clr	(r0)+
+	mov	(r0),r2
+	clr	(r0)+
+	mov	(r0),r3
+	clr	(r0)+
+	mov	(r0),r4
+	clr	(r0)+
+	mov	$fpwork+2,r5
+	mov	$200,-(sp)
+	mov	$fpwork2+4,r0
+1:
+	cmp	(r0)+,r1
+	blt	2f
+	bgt	3f
+	cmp	(r0)+,r2
+	bcs	2f
+	bhi	3f
+	cmp	(r0)+,r3
+	bcs	2f
+	bhi	3f
+	cmp	(r0)+,r4
+	bhi	3f
+2:
+	mov	$fpwork2+4,r0
+	sub	(r0)+,r1
+	clr	-(sp)
+	sub	(r0)+,r2
+	adc	(sp)
+	clr	-(sp)
+	sub	(r0)+,r3
+	adc	(sp)
+	sub	(r0)+,r4
+	sbc	r3
+	adc	(sp)
+	sub	(sp)+,r2
+	adc	(sp)
+	sub	(sp)+,r1
+	bis	(sp),(r5)
+3:
+	asl	r4
+	rol	r3
+	rol	r2
+	rol	r1
+	clc
+	ror	(sp)
+	bne	1b
+	mov	$100000,(sp)
+	add	$2,r5
+	cmp	r5,$fpwork2+6
+	bcs	1b
+	tst	(sp)+
+	mov	(sp)+,r5
+	jmp	fpst2
+
+fpmul2:
+	jsr	pc,fpld
+	sub	fpwork2+10.,fpwork2+8.
+	inc	fpwork2+8.
+	jsr	pc,fpsgn
+	mov	r5,-(sp)
+	mov	$fpwork2+6,r5
+	bit	$200,fpflags
+	beq	1f
+	add	$4,r5
+1:
+	clr	r0
+	clr	r1
+	clr	r2
+	clr	r3
+	clr	r4
+1:
+	asl	r0
+	bne	2f
+	inc	r0
+	tst	-(r5)
+2:
+	cmp	r0,$400
+	bne	3f
+	cmp	r5,$fpwork2+4
+	bhi	3f
+	mov	$fpwork+2,r0
+	mov	r1,(r0)+
+	mov	r2,(r0)+
+	mov	r3,(r0)+
+	mov	r4,(r0)+
+	mov	(sp)+,r5
+	rts	pc
+3:
+	clc
+	ror	r1
+	ror	r2
+	ror	r3
+	ror	r4
+	bit	r0,(r5)
+	beq	1b
+	mov	r0,-(sp)
+	mov	$fpwork+2,r0
+	add	(r0)+,r1
+	clr	-(sp)
+	add	(r0)+,r2
+	adc	(sp)
+	clr	-(sp)
+	add	(r0)+,r3
+	adc	(sp)
+	add	(r0)+,r4
+	adc	r3
+	adc	(sp)
+	add	(sp)+,r2
+	adc	(sp)
+	add	(sp)+,r1
+	mov	(sp)+,r0
+	br	1b
+
+fpsgn:
+	cmp	fpwork,fpwork2+8.
+	beq	1f
+	mov	$-1,fpwork
+	rts	pc
+1:
+	mov	$1,fpwork
+	rts	pc
+
+/ floating point data area
+fpwork:
+	0
+fpwork+2:
+	0
+	0
+	0
+	0
+	0
+fpwork2+8.:
+	0
+fpwork2+10.:
+	0
+	0
+	0
+	0
+	0
+fpflags:
+	0
+fperr:
+	0
+fpac:
+	0; 0; 0; 0
+	0; 0; 0; 0
+	0; 0
+fpr0:
+	0
+fpregs:
+	0; 0; 0; 0
+	0; 0; 0
+fppc:
+	0
+fpps:
+	0
+
+/ read integer using EAE
+rdint:
+	clr	@$mq
+	jsr	r5, at 0(r5)
+	clr	-(sp)
+	cmp	r0,$'-
+	bne	1f
+	inc	(sp)
+	jsr	r5, at 0(r5)
+1:
+	sub	$'0,r0
+	cmp	r0,$11
+	bhi	2f
+	mov	$12,@$mul
+	add	r0,@$mq
+	br	.-20
+2:
+	add	$'0,r0
+	tst	(sp)+
+	beq	1f
+	neg	@$mq
+1:
+	tst	(r5)+
+	rts	r5
+
+/ print float using FPU
+prflt:
+	mov	r4,-(sp)
+	mov	r3,-(sp)
+	ldf	$12.,f3
+	ldf	$1,f2
+	clr	r4
+	stf	f0,r1
+	mulf	4f,f1
+	addf	r1,f0
+	tstf	r0
+	cfcc
+	beq	3f
+	bge	1f
+	negf	r0
+	mov	$'-,r0
+	jsr	r5, at 0(r5)
+1:
+	cmpf	r3,f0
+	cfcc
+	bgt	2f
+	inc	r4
+	divf	r3,f0
+	br	1b
+2:
+	cmpf	r2,f0
+	cfcc
+	ble	3f
+	dec	r4
+	mulf	r3,f0
+	br	2b
+3:
+	modf	r2,f0
+	stcfi	f0,r0
+	add	$'0,r0
+	jsr	r5, at 0(r5)
+	mov	$'.,r0
+	jsr	r5, at 0(r5)
+	mov	$10.,r3
+4:
+	modf	r3,f0
+	stcfi	f0,r0
+	add	$'0,r0
+	jsr	r5, at 0(r5)
+	dec	r3
+	bgt	4b
+	mov	$'e,r0
+	jsr	r5, at 0(r5)
+	mov	r4,r0
+	mov	(sp)+,r3
+	mov	(sp)+,r4
+	jmp	prdec
+
+4:	.flt2 0.5
+	0; 0; 0
+
+/ print decimal
+prdec:
+	mov	r0,@$mq
+	bge	1f
+	neg	@$mq
+	mov	$'-,r0
+	jsr	r5, at 0(r5)
+1:
+	jsr	pc,prdec2
+	tst	(r5)+
+	rts	r5
+
+prdec2:
+	clr	@$ac
+	mov	$12,@$div
+	mov	@$ac,-(sp)
+	tst	@$mq
+	beq	1f
+	jsr	pc,prdec2
+1:
+	mov	(sp)+,r0
+	add	$'0,r0
+	jsr	r5, at 0(r5)
+	rts	pc
+
+/ read float using FPU
+rdflt:
+	mov	r1,-(sp)
+	mov	r2,-(sp)
+	ldf	$12.,f3
+	clr	r2
+	clrf	r0
+	clr	-(sp)
+	jsr	r5, at 0(r5)
+	cmp	r0,$'-
+	bne	1f
+	inc	(sp)
+	jsr	r5, at 0(r5)
+1:
+	sub	$'0,r0
+	cmp	r0,$11
+	bhi	2f
+	mulf	r3,f0
+	ldcif	r0,f1
+	addf	r1,f0
+	dec	r1
+	br	.-20
+2:
+	add	$'0,r0
+	cmp	r0,$'.
+	bne	3f
+	clr	r1
+	inc	r2
+	br	.-30
+3:
+	clr	@$mq
+	cmp	r0,$'e
+	bne	4f
+	mov	(r5),.-6
+	jsr	r5,rdint
+	0
+4:
+	tst	r2
+	bne	1f
+	clr	r1
+1:
+	add	@$mq,r1
+	tst	r1
+	bge	1f
+	divf	r3,f0
+	inc	r1
+	br	.-10
+1:
+	tst	r1
+	ble	1f
+	mulf	r3,f0
+	dec	r1
+	br	.-10
+1:
+	tst	(sp)+
+	beq	1f
+	negf	r0
+1:
+	mov	(sp)+,r2
+	mov	(sp)+,r1
+	tst	(r5)+
+	rts	r5
+
+/ trigonometric functions
+fpsin:
+	addf	4f,f0
+	clr	-(sp)
+	tstf	r0
+	cfcc
+	bge	1f
+	negf	r0
+	inc	(sp)
+1:
+	modf	5f,f0
+	mulf	4f,f0
+	stcfi	f0,r0
+	ror	r0
+	bcc	1f
+	negf	r0
+	addf	4f,f0
+1:
+	ror	r0
+	sbc	(sp)
+	stf	f0,r1
+	stf	f0,r2
+	mulf	r2,f0
+	ldf	$1,f3
+	stf	f3,r4
+	mov	$12,r0
+1:
+	addf	r4,f3
+	negf	r1
+	mulf	r2,f1
+	divf	r3,f1
+	addf	r4,f3
+	divf	r3,f1
+	addf	r1,f0
+	dec	r0
+	bne	1b
+	tst	(sp)+
+	beq	1f
+	negf	r0
+1:
+	rts	r5
+
+4:	.flt2 3.14159265359
+	0; 0; 0; 0
+
+5:	.flt2 0.31830988618
+	0; 0; 0; 0
+
+/ exponential function
+fpexp:
+	ldf	$1,f1
+	ldf	$2,f2
+	tstf	r0
+	cfcc
+	bne	1f
+	stf	f1,r0
+	rts	r5
+1:
+	bgt	2f
+	negf	r0
+	mov	pc,-(sp)
+	br	3f
+2:
+	clr	-(sp)
+3:
+	clr	-(sp)
+	divf	r2,f0
+	cmpf	r1,f0
+	cfcc
+	bge	1f
+	inc	(sp)
+	br	.-12
+1:
+	stf	f0,-(sp)
+	mulf	r0,f0
+	stf	f0,r5
+	clrf	r0
+	ldf	$23,f3
+	mov	$12,r0
+1:
+	addf	r3,f0
+	stf	f0,r4
+	ldf	r5,f0
+	divf	r4,f0
+	subf	r2,f3
+	dec	r0
+	bgt	1b
+	subf	r0,f1
+	ldf	(sp)+,f0
+	addf	r0,f0
+	divf	r1,f0
+	mov	(sp)+,r0
+	beq	1f
+	mulf	r0,f0
+	dec	r0
+	bgt	.-4
+1:
+	tst	(sp)+
+	beq	1f
+	divf	r0,f1
+	stf	f1,r0
+1:
+	rts	r5
+
+/ logarithm function
+fplog:
+	tstf	r0
+	cfcc
+	bgt	1f
+	sec
+	rts	r5
+1:
+	clr	-(sp)
+	cmpf	6f,f0
+	cfcc
+	bge	1f
+	divf	7f,f0
+	inc	(sp)
+	br	.-14
+1:
+	cmpf	8f,f0
+	cfcc
+	ble	1f
+	mulf	7f,f0
+	dec	(sp)
+	br	.-14
+1:
+	ldf	$1,f1
+	stf	f0,r2
+	addf	r1,f2
+	subf	r1,f0
+	divf	r2,f0
+	stf	f0,-(sp)
+	mulf	r0,f0
+	stf	f0,r4
+	mov	$12,r0
+	ldcif	r0,f2
+	ldf	$25,f3
+	clrf	r0
+	negf	r0
+	addf	r3,f0
+	stf	f0,r5
+	stf	r0,f2
+	mulf	r2,f0
+	mulf	r4,f0
+	divf	r5,f0
+	subf	r1,f2
+	subf	f3,7f
+	dec	r0
+	bgt	.-34
+	subf	r0,f1
+	ldf	(sp)+,f0
+	addf	r0,f0
+	divf	r1,f0
+	mov	(sp)+,r0
+	beq	1f
+	ldcif	r0,f1
+	mulf	9f,f1
+	addf	r1,f0
+1:
+	clc
+	rts	r5
+
+6:	.flt2 10.0
+	0; 0; 0; 0
+
+7:	.flt2 1.0
+	0; 0; 0; 0
+
+8:	.flt2 0.1
+	0; 0; 0; 0
+
+9:	.flt2 2.302585093
+	0; 0; 0; 0
+
+/ initialization
+init:
+	trap	41
+	setd
+	trap	33
+	mov	sp,spsave
+	mov	r6,spsave
+	clr	lineno
+	mov	$'a,r1
+1:
+	movb	r1,inbuf+142.
+	trap	22
+	0f:..; 0
+	bcs	1f
+	inc	r1
+	cmp	r1,$'z
+	blos	1b
+	br	2f
+1:
+	trap	10
+	0f:..; 14
+	bcs	2f
+	mov	r0,tmpfd
+	trap	5
+	0f:..
+	0
+
+	bcc	2f
+2:
+	mov	$ermsg1,r0
+	jsr	pc,prmsg
+	trap	1
+tmpnam:	<Tmp file\0>
+	.even
+	clr	@0f
+2:
+	mov	r0,infd
+	jsr	pc,reset
+	cmp	(sp),$2
+	blt	1f
+	mov	4(sp),0f
+	trap	5
+	0:..
+	0
+
+	bcc	2f
+	mov	r0,filfd
+	br	1f
+2:
+	mov	$ermsg2,r0
+	jsr	pc,prmsg
+	br	1f
+
+ermsg2:	<Cannot open file\n\0>
+	.even
+1:
+	mov	$'\n,r0
+	jsr	r5,putc
+	jsr	r5,rdline
+	<ready\n\0>
+	.even
+1:
+	mov	spsave,sp
+	clr	runflg
+	jsr	pc,getlin
+	mov	$inbuf,r3
+	movb	(r3),r0
+	jsr	pc,ckdgt
+	br	1f
+
+/ read line number
+rnum:
+	jsr	r5,rdint
+	2f
+	cmp	r0,$'
+	beq	1f
+	mov	$lines,r3
+1:
+	mov	@$mq,r0
+	bgt	1f
+	jsr	pc,errlin
+1:
+	tst	-(r3)
+	beq	2f
+	cmp	r0,(r3)
+	beq	3f
+	cmp	-(r3),-(r3)
+	br	1b
+2:
+	clr	-6(r3)
+3:
+	mov	r0,(r3)
+	mov	lineno,-(r3)
+	mov	tmpfd,r0
+	trap	23
+	0:..
+	0
+
+	mov	$inbuf,r0
+	jsr	pc,prlin
+	inc	r0
+	add	r0,lineno
+	mov	r0,0f
+	mov	tmpfd,r0
+	trap	4
+	inbuf; 0:..
+	br	restart
+
+1:
+	mov	$inbuf,r3
+	jsr	pc,parse
+	br	restart
+
+/ print message
+prmsg:
+	movb	(r3)+,r0
+	emt	5
+prlin:
+	clr	-(sp)
+1:
+	inc	(sp)
+	cmpb	(r0)+,$'\n
+	bne	1b
+	mov	(sp)+,r0
+	emt	7
+	tst	saveit
+	beq	1f
+	mov	$1,r0
+	trap	4
+	savbuf; 3
+	clr	saveit
+1:
+	emt	7
+getlin:
+	jsr	pc,.-6
+	mov	$inbuf,0f
+	mov	filfd,r0
+	trap	3
+	0:..
+	1
+	bcs	1f
+	tst	r0
+	beq	1f
+	movb	@.-14,r0
+	inc	.-16
+	cmp	r0,$'\n
+	bne	getlin
+	clrb	@.-24
+	emt	7
+1:
+	mov	filfd,r0
+	beq	1f
+	trap	6
+	clr	filfd
+	br	getlin
+1:
+	jmp	done
+
+/ read line routine
+rdline:
+	mov	filfd,r0
+	beq	1f
+	trap	6
+	clr	filfd
+1:
+	tst	runflg
+	beq	1f
+	jsr	pc,fndlin
+	br	1f
+ermsg1:
+	mov	$inbuf,r0
+	jsr	pc,prmsg
+	jmp	restart
+
+1:
+	mov	spsave,sp
+	jsr	pc,getlin
+	cmp	r0,$'
+	beq	1b
+	movb	(r3)+,r0
+	jmp	@rdtbl(r1)
+
+rdtbl:
+	rd1; rd2
+	rd3; rd4
+	rd5; rd6
+	rd7; rd8
+	rd9; rd10
+	rd11; rd12
+
+/ error handler
+errlin:
+	dec	r3
+	mov	filfd,r0
+	beq	1f
+	trap	6
+	clr	filfd
+1:
+	mov	$inbuf,r1
+	cmp	r1,r3
+	bne	2f
+	mov	$'_,r0
+	jsr	r5,putc
+	mov	$10,r0
+	jsr	r5,putc
+2:
+	movb	(r1),r0
+	jsr	r5,putc
+	cmpb	(r1)+,$'\n
+	bne	.-10
+	jmp	restart
+
+/ check if digit
+ckdgt:
+	cmp	r0,$'0
+	bcs	1f
+	cmp	r0,$'9
+	bhi	1f
+	add	$2,(sp)
+1:
+	emt	7
+	cmp	r0,$'a
+	bcs	1f
+	cmp	r0,$'z
+	bhi	1f
+	add	$2,(sp)
+1:
+	emt	7
+	mov	$name,r1
+	clr	(r1)
+	clr	2(r1)
+	cmp	r1,$name+4
+	bcc	1f
+	movb	r0,(r1)+
+1:
+	movb	(r3)+,r0
+	jsr	pc,ckdgt+10
+	br	.-4
+	jsr	pc,ckdgt
+	br	.-4
+
+/ lookup keyword
+ckkey:
+	mov	$kwtbl,r1
+1:
+	cmp	name,(r1)
+	bne	2f
+	cmp	name+2,2(r1)
+	bne	2f
+	sub	$kwtbl,r1
+	asr	r1
+	add	$2,(sp)
+	emt	7
+2:
+	add	$4,r1
+	cmp	r1,$kwtbl+50.
+	bcs	1b
+	mov	$vars,r1
+1:
+	tst	(r1)
+	beq	2f
+	cmp	name,(r1)
+	bne	3f
+	cmp	name+2,2(r1)
+	bne	3f
+	emt	7
+3:
+	add	$16,r1
+	br	1b
+2:
+	mov	name,(r1)
+	mov	name+2,2(r1)
+	clr	4(r1)
+	clr	16(r1)
+	emt	7
+skipsp:
+	cmp	r0,$'
+	bne	1f
+	movb	(r3)+,r0
+	br	skipsp
+1:
+	emt	7
+putc:
+	mov	r0,0f
+	mov	$1,r0
+	trap	4
+	0f:..; 1
+	emt	5
+	0
+	0
+
+/ find line
+fndlin:
+	clr	-(sp)
+	mov	$lines,r1
+1:
+	tst	-(r1)
+	beq	2f
+	cmp	runflg,(r1)
+	bhi	3f
+	mov	(sp),r0
+	beq	4f
+	cmp	(r0),(r1)
+	blos	3f
+4:
+	mov	r1,(sp)
+3:
+	cmp	-(r1),-(r1)
+	br	1b
+2:
+	mov	(sp)+,r1
+	beq	1f
+	mov	(r1),runflg
+	mov	-(r1),0f
+	mov	infd,r0
+	trap	23
+	0:..
+	0
+
+	mov	infd,r0
+	trap	3
+	inbuf; 144.
+	add	$2,(sp)
+1:
+	emt	7
+look:
+	mov	$lines,r1
+1:
+	tst	-(r1)
+	beq	2f
+	cmp	r0,(r1)
+	beq	3f
+	cmp	-(r1),-(r1)
+	br	1b
+2:
+	jsr	r5,errmsg
+	<label not found\0>
+	.even
+3:
+	emt	7
+reset:
+	mov	$vars,r0
+	mov	$kwtbl+50.,r1
+	clrf	r0
+	ldf	$1,f1
+1:
+	mov	(r1)+,(r0)+
+	mov	(r1)+,(r0)+
+	mov	$1,(r0)+
+	subf	r1,f0
+	stf	f0,(r0)+
+	cmp	r1,$vars
+	bcs	1b
+	clr	(r0)+
+	emt	7
+initst:
+	clr	curlvl
+	mov	$code,r4
+	tst	runflg
+	beq	1f
+	emt	7
+1:
+	jsr	pc,fndlin
+	br	stmt
+stmt:
+	mov	runflg,r0
+	jsr	pc,look
+	mov	-4(r1),r4
+	jsr	pc,parse
+	br	1f
+1:
+	inc	runflg
+	br	1b
+
+parse:
+	tst	curlvl
+	bne	1f
+	mov	$goto,(r4)+
+	emt	7
+stmt2:
+	clr	curlvl
+	mov	$lines,r4
+1:
+	tst	-(r3)
+	beq	2f
+	cmp	-(r3),-(r3)
+	br	1b
+2:
+	mov	r3,curlin
+	jmp	(r4)+
+
+/ execute loop
+exec:
+	tstf	(r3)+
+	cfcc
+	beq	1f
+	tst	(r4)+
+	jmp	(r4)+
+1:
+	mov	(r4)+,r4
+	jmp	(r4)+
+
+/ call subroutine
+call:
+	mov	r4,-(r3)
+	mov	curlin,-(r3)
+	mov	r3,curlin
+	inc	curlvl
+	clr	r0
+	jsr	pc,getarg
+	tstf	r0
+	cfcc
+	bge	1f
+	jmp	return
+1:
+	ldf	(r3),f0
+	stf	f0,-(sp)
+	jsr	pc,initst
+	mov	(sp)+,r0
+	jsr	pc,look
+	mov	-4(r1),r4
+	jmp	(r4)+
+
+/ run
+run:
+	jsr	pc,reset
+	mov	$1,runflg
+	jsr	pc,initst
+	mov	$code,r4
+	jmp	(r4)+
+
+/ print statement
+print:
+	clr	prtab
+	tstf	(r3)+
+	cfcc
+	bne	1f
+	mov	$100,prtab
+1:
+	jsr	r5,prchr
+	inbuf; inbuf+10.
+	jsr	r5,prchr
+	inbuf+10.; inbuf+20.
+	jsr	pc,output
+	jmp	(r4)+
+
+prchr:
+	ldf	(r3)+,f0
+	ldf	$1000.,f1
+	mulf	r1,f0
+	stcfi	f0,r0
+	tst	r0
+	bge	1f
+	clr	r0
+1:
+	cmp	r0,$1000.
+	blt	1f
+	mov	$777,r0
+1:
+	mov	r0,@(r5)+
+	emt	5
+curlin:
+	mov	curlin,r3
+	mov	(r4)+,runflg
+	jmp	(r4)+
+
+/ comparison operations
+cmpz:
+	tstf	(r3)+
+	cfcc
+	beq	1f
+	clrf	r0
+	br	2f
+1:
+	ldf	$1,f0
+2:
+	stf	f0,(r3)
+	jmp	(r4)+
+
+cmpnz:
+	tstf	(r3)+
+	cfcc
+	bne	1f
+	tstf	(r3)
+	cfcc
+	bne	1f
+	br	2f
+cmplt:
+	tstf	(r3)+
+	cfcc
+	beq	2f
+	tstf	(r3)
+	cfcc
+	beq	2f
+	br	1f
+cmpeq:
+	jsr	pc,cmpsub
+	bgt	1f
+	br	2f
+cmpgt:
+	jsr	pc,cmpsub
+	blt	1f
+	br	2f
+cmple:
+	jsr	pc,cmpsub
+	bge	1f
+	br	2f
+cmpge:
+	jsr	pc,cmpsub
+	ble	1f
+	br	2f
+cmpne:
+	jsr	pc,cmpsub
+	bne	1f
+	br	2f
+cmpeq2:
+	jsr	pc,cmpsub
+	beq	1f
+2:
+	clrf	r0
+	br	3f
+1:
+	ldf	$1,f0
+3:
+	stf	f0,(r3)
+	jmp	(r4)+
+
+/ store/load float
+stflt:
+	stf	f1,r0
+	br	1f
+ldflt:
+	ldf	(r3),f0
+	mov	10(r3),r0
+	add	$4,r0
+	bis	$1,(r0)+
+	stf	f0,(r0)
+	tst	(r3)+
+	br	2f
+
+/ arithmetic operations
+addf:
+	ldf	(r3)+,f0
+	addf	(r3),f0
+	br	2f
+subf:
+	ldf	(r3)+,f0
+	negf	r0
+	addf	(r3),f0
+	br	2f
+mulf:
+	ldf	(r3)+,f0
+	mulf	(r3),f0
+	br	2f
+divf:
+	ldf	(r3)+,f1
+	ldf	(r3),f0
+	divf	r1,f0
+	br	2f
+powf:
+	ldf	10(r3),f0
+	jsr	r5,fplog
+	mulf	(r3)+,f0
+	jsr	r5,fpexp
+	br	2f
+pushf:
+	ldf	(r4)+,f0
+1:
+	stf	f0,-(r3)
+	jmp	(r4)+
+2:
+	stf	f0,(r3)
+	jmp	(r4)+
+
+ldval:
+	jsr	pc,getval
+	br	1b
+ldval2:
+	jsr	pc,getval
+	ldf	$1,f1
+	addf	r1,f0
+	stf	f0,(r0)
+	br	1b
+
+pushval:
+	mov	(r4)+,-(r3)
+	jmp	(r4)+
+ldflt2:
+	ldf	(r3),f0
+	br	1b
+
+/ return from subroutine
+return:
+	dec	curlvl
+	bge	1f
+	jsr	r5,errmsg
+	<bad return\0>
+	.even
+1:
+	ldf	(r3),f0
+	mov	curlin,r3
+	mov	(r3)+,curlin
+	mov	(r3)+,r4
+	mov	(r4)+,r0
+	dec	r0
+	blt	2f
+	add	$10,r3
+	br	.-10
+2:
+	iot
+
+cmpsub:
+	ldf	(r3)+,f1
+	cmpf	(r3),f1
+	cfcc
+	emt	7
+getval:
+	mov	(r3)+,r0
+	add	$4,r0
+	bit	$1,(r0)+
+	bne	1f
+	jsr	r5,errmsg
+	<used before set\0>
+	.even
+1:
+	ldf	(r0),f0
+	emt	7
+return2:
+	dec	curlvl
+	mov	(r3)+,curlin
+	mov	(r3)+,r4
+	stcfi	f0,r0
+	com	r0
+	asl	r0
+	cmp	r0,$22
+	bcc	1f
+	jmp	@bltbl(r0)
+
+bltbl:
+	bl1; bl2; bl3; bl4
+	bl5; bl6; bl7; bl8
+	bl9
+bl1:
+	mov	$-1,r0
+	jsr	pc,prdec+6
+	br	done
+bl2:
+	cmp	(r4)+,$1
+	bne	1f
+	ldf	(r3),f0
+	stcfi	f0,r0
+	jsr	pc,getarg
+	br	done
+bl3:
+	jsr	r5,blcall
+	sqrtf; done
+bl4:
+	jsr	r5,blcall
+	sinf; done
+bl5:
+	jsr	r5,blcall
+	cosf; done
+bl6:
+	jsr	r5,blcall
+	atanf; done
+bl7:
+	tst	(r4)+
+	bne	1f
+	mov	rndval,@$mq
+	mov	$40647,@$mul
+	mov	@$mq,r0
+	mov	r0,rndval
+	ldcif	r0,f0
+	absf	r0
+	divf	4f,f0
+	jmp	2f
+4:	.flt2 32768.
+	0; 0; 0; 0
+bl8:
+	tst	(r4)+
+	bne	1f
+	mov	r3,-(sp)
+	mov	r4,-(sp)
+	jsr	pc,getlin
+	mov	curlvl+4,r4
+	mov	$inbuf,r3
+	jsr	pc,parse
+	mov	#goto,(r4)+
+	mov	(sp)+,(r4)+
+	mov	(sp)+,r3
+	mov	curlvl+4,r4
+	add	$10,r3
+	jmp	(r4)+
+bl9:
+	cmp	(r4)+,$1
+	bne	1f
+	ldf	(r3),f0
+	ldf	$1,f1
+	modf	r1,f0
+	stf	f1,r0
+	br	2b
+2:
+	add	$10,r3
+	jmp	2f
+1:
+	jsr	r5,errmsg
+	<arg count\0>
+	.even
+getarg:
+	tst	curlvl
+	beq	1f
+	mov	curlin,r1
+	sub	@2(r1),r0
+	bhi	1f
+	inc	r0
+	bgt	2f
+	add	$10,r1
+	br	.-10
+2:
+	ldf	4(r1),f0
+	emt	7
+1:
+	jsr	r5,errmsg
+	<bad arg\0>
+	.even
+blcall:
+	cmp	(r4)+,$1
+	bne	1b
+	ldf	(r3),f0
+	mov	(r5)+,0f
+	jsr	r5,@$0f
+	0
+	emt	5
+output:
+	tst	saveit
+	bne	1f
+	mov	$1,r0
+	trap	4
+	savbuf; 3
+	inc	saveit
+1:
+	mov	tab1,r0
+	jsr	pc,dopos
+	asl	r0
+	asl	r0
+	asl	r0
+	mov	r0,-(sp)
+	mov	tab2,r0
+	jsr	pc,dopos
+	bis	(sp)+,r0
+	bis	prtab,r0
+	beq	2f
+	cmp	r0,$11
+	bcs	3f
+	cmp	r0,$15
+	blos	2f
+	cmp	r0,$177
+	bne	3f
+	dec	r0
+	br	3f
+2:
+	add	$10,r0
+3:
+	mov	r0,0f
+	mov	$1,r0
+	trap	4
+	0f:..; 1
+	emt	7
+	0
+
+dopos:
+	mov	r0,-(sp)
+	asr	r0
+	asr	r0
+	asr	r0
+	bic	$177700,r0
+	cmp	r0,$77
+	beq	1f
+	bis	$100,r0
+1:
+	jsr	pc,.-20
+	mov	(sp)+,r0
+	bic	$177770,r0
+	emt	7
+
+/ keyword table
+kwtbl:
+	</ >
+	<tmp>
+	</b>
+	<list>
+	<done>
+	<run>
+	<print>
+	<if>
+
+	<goto>
+	<return>
+	<for>
+	<next>
+	<draw>
+	<arg>
+
+	<exp>
+	<log>
+
+	<sin>
+	<cos>
+	<atn>
+
+	<rnd>
+	<exp>
+	<print>
+	1
+
+.bss
+spsave:	.=.+2
+infd:	.=.+2
+filfd:	.=.+2
+tmpfd:	.=.+2
+lineno:	.=.+2
+runflg:	.=.+2
+curlvl:	.=.+2
+saveit:	.=.+2
+prtab:	.=.+2
+tab1:	.=.+2
+tab2:	.=.+2
+rndval:	.=.+2
+name:	.=.+4
+inbuf:	.=.+150.
+savbuf:	.=.+4
+lines:	.=.+1024.
+vars:	.=.+1024.
+code:	.=.+2048.
diff --git a/cmd/cc.s b/cmd/cc.s
new file mode 100644
index 0000000..0a7f168
--- /dev/null
+++ b/cmd/cc.s
@@ -0,0 +1,871 @@
+/ cc -- C compiler driver
+
+	br	start
+	jsr	r5, at 416.(sp)
+	bne	1f
+	ble	37777777522
+	0
+	0
+symend:	1
+
+start:
+	mov	$mq,r4
+	mov	sp,r0
+	mov	(r0),-(sp)
+	tst	(r0)+
+	mov	r0,2(sp)
+	jsr	pc, at main
+	clr	r0
+	sys	exit
+	mov	r5,sp
+	mov	(sp)+,r5
+	rts	pc
+
+/ main function
+main:
+	mov	r5,-(sp)
+	mov	sp,r5
+	add	$-102.,sp
+	mov	sp,r0
+	mov	r0,-(sp)
+	add	$-500.,sp
+	mov	sp,r0
+	mov	r0,-(sp)
+	add	$-212.,sp
+	mov	sp,r0
+	mov	r0,-(sp)
+	add	$-100.,sp
+	mov	sp,r0
+	mov	r0,-(sp)
+	add	$-100.,sp
+	mov	sp,r0
+	mov	r0,-(sp)
+	mov	$tmp0,r0
+	mov	r0,tmp3
+	mov	r0,tmp2
+	mov	r0,tmp1
+	mov	r0,tmp0
+	mov	-102.(r5),tsp
+	clr	r0
+	mov	r0,-2(r5)
+	mov	r0,-102.(r5)
+	mov	r0,-104.(r5)
+	mov	r0,-98.(r5)
+
+/ main argument processing loop
+1:
+	inc	-98.(r5)
+	mov	-98.(r5),r0
+	cmp	r0,4(r5)
+	blt	2f
+	jmp	done
+2:
+	mov	-98.(r5),r0
+	asl	r0
+	add	6(r5),r0
+	mov	(r0),r0
+	cmpb	(r0),$'-
+	bne	3f
+	mov	-98.(r5),r0
+	asl	r0
+	add	6(r5),r0
+	mov	(r0),r0
+	cmpb	1(r0),$'c
+	bne	3f
+	inc	-2(r5)
+	jmp	1b
+3:
+	mov	-98.(r5),r0
+	asl	r0
+	add	6(r5),r0
+	mov	(r0),r0
+	mov	r0,-(sp)
+	jsr	pc, at copy
+	tst	(sp)+
+	mov	r0,-108.(r5)
+	mov	-108.(r5),-(sp)
+	jsr	pc, at getsuf
+	tst	(sp)+
+	mov	r0,-96.(r5)
+	cmp	r0,$'c
+	beq	4f
+	jmp	notc
+4:
+	/ .c file
+	mov	-104.(r5),r0
+	inc	-104.(r5)
+	asl	r0
+	add	-104.(r5),r0
+	mov	-108.(r5),(r0)
+	mov	-108.(r5),-(sp)
+	jsr	pc, at copy
+	tst	(sp)+
+	mov	r0,-(sp)
+	jsr	pc, at setsuf
+	tst	(sp)+
+	mov	-102.(r5),r1
+	inc	-102.(r5)
+	asl	r1
+	add	-500.(r5),r1
+	mov	r0,(r1)
+	jmp	1b
+
+notc:
+	/ not .c file
+	mov	-108.(r5),-(sp)
+	mov	-500.(r5),-(sp)
+	jsr	pc, at nodup
+	cmp	(sp)+,(sp)+
+	tst	r0
+	beq	1b
+	mov	-102.(r5),r0
+	inc	-102.(r5)
+	asl	r0
+	add	-500.(r5),r0
+	mov	-108.(r5),(r0)
+	jmp	1b
+
+done:
+	tst	-104.(r5)
+	bne	1f
+	jmp	@finis
+1:
+	/ setup temp file
+	mov	$tmpfn,-(sp)
+	jsr	pc, at copy
+	tst	(sp)+
+	mov	r0,tmp0
+	clr	-(sp)
+	mov	tmp0,-(sp)
+	jsr	pc, at creat
+	cmp	(sp)+,(sp)+
+	mov	r0,-96.(r5)
+	tst	r0
+	bge	1f
+	jmp	badcreat
+1:
+	mov	-96.(r5),-(sp)
+	jsr	pc, at close
+	tst	(sp)+
+	mov	tmp0,r0
+	incb	11.(r0)
+	jmp	opentmp
+
+badcreat:
+	mov	$'\n,-(sp)
+	mov	tmp0,-(sp)
+	jsr	pc, at link
+	cmp	(sp)+,(sp)+
+	tst	r0
+	bge	1f
+	mov	tmp0,r0
+	incb	11.(r0)
+	br	badcreat
+1:
+	mov	fout,-(sp)
+	jsr	pc, at flush
+	tst	(sp)+
+
+	/ setup temp file names
+	mov	tmp0,-(sp)
+	jsr	pc, at copy
+	tst	(sp)+
+	mov	r0,tmp1
+	movb	$'1,10.(r0)
+	mov	tmp0,-(sp)
+	jsr	pc, at copy
+	tst	(sp)+
+	mov	r0,tmp2
+	movb	$'2,10.(r0)
+	mov	tmp0,-(sp)
+	jsr	pc, at copy
+	tst	(sp)+
+	mov	r0,tmp3
+	movb	$'3,10.(r0)
+
+	/ compile each file
+	clr	-98.(r5)
+cloop:
+	cmp	-98.(r5),-104.(r5)
+	blt	1f
+	jmp	linkstep
+1:
+	cmp	-104.(r5),$1
+	ble	1f
+	mov	-98.(r5),r0
+	asl	r0
+	add	-104.(r5),r0
+	mov	(r0),r0
+	mov	r0,-(sp)
+	mov	$cmsg,-(sp)
+	jsr	pc, at printf
+	cmp	(sp)+,(sp)+
+1:
+	/ setup c0 args
+	mov	-706.(r5),r0
+	mov	$c0,(r0)
+	mov	-706.(r5),r0
+	mov	-98.(r5),r1
+	asl	r1
+	add	-104.(r5),r1
+	mov	(r1),2(r0)
+	mov	-706.(r5),r0
+	mov	tmp1,4(r0)
+	mov	-706.(r5),r0
+	mov	tmp2,6(r0)
+	mov	-706.(r5),r0
+	clr	10.(r0)
+	mov	-706.(r5),-(sp)
+	mov	$c0path,-(sp)
+	jsr	pc, at callsys
+	cmp	(sp)+,(sp)+
+	tst	r0
+	beq	1f
+	jmp	c0err
+1:
+	inc	-2(r5)
+	jmp	@finis
+
+c0err:
+	/ setup c1 args
+	mov	-706.(r5),r0
+	mov	$c1,(r0)
+	mov	-706.(r5),r0
+	mov	tmp1,2(r0)
+	mov	-706.(r5),r0
+	mov	tmp2,4(r0)
+	mov	-706.(r5),r0
+	mov	tmp3,6(r0)
+	mov	-706.(r5),r0
+	clr	10.(r0)
+	mov	-706.(r5),-(sp)
+	mov	$c1path,-(sp)
+	jsr	pc, at callsys
+	cmp	(sp)+,(sp)+
+	tst	r0
+	beq	1f
+	jmp	c1err
+1:
+	inc	-2(r5)
+	jmp	@finis
+
+c1err:
+	/ setup as args
+	mov	-706.(r5),r0
+	mov	$as,(r0)
+	mov	-706.(r5),r0
+	mov	$asflag,2(r0)
+	mov	-706.(r5),r0
+	mov	tmp3,4(r0)
+	mov	-706.(r5),r0
+	clr	6(r0)
+	mov	-706.(r5),-(sp)
+	mov	$aspath,-(sp)
+	jsr	pc, at callsys
+	cmp	(sp)+,(sp)+
+	mov	-98.(r5),r0
+	asl	r0
+	add	-104.(r5),r0
+	mov	(r0),r0
+	mov	r0,-(sp)
+	jsr	pc, at setsuf
+	tst	(sp)+
+	mov	r0,-108.(r5)
+	mov	-108.(r5),-(sp)
+	jsr	pc, at unlink
+	tst	(sp)+
+	mov	-108.(r5),-(sp)
+	mov	$oext,-(sp)
+	jsr	pc, at nodup
+	cmp	(sp)+,(sp)+
+	tst	r0
+	bne	movout
+	mov	$sext,-(sp)
+	jsr	pc, at unlink
+	tst	(sp)+
+	tst	r0
+	bne	movout
+	jmp	nextfile
+
+movout:
+	mov	-108.(r5),-(sp)
+	mov	$mvmsg,-(sp)
+	jsr	pc, at printf
+	cmp	(sp)+,(sp)+
+	inc	-2(r5)
+nextfile:
+	inc	-98.(r5)
+	jmp	cloop
+
+linkstep:
+	tst	-2(r5)
+	bne	1f
+	tst	-102.(r5)
+	bne	2f
+1:
+	jmp	cleanup
+2:
+	/ link step
+	clr	-98.(r5)
+	mov	-706.(r5),r0
+	mov	$ld,(r0)
+	mov	-706.(r5),r0
+	mov	$ldpath,2(r0)
+	mov	$2,-100.(r5)
+	cmp	-98.(r5),-102.(r5)
+	bge	3f
+1:
+	mov	-100.(r5),r0
+	inc	-100.(r5)
+	asl	r0
+	add	-706.(r5),r0
+	mov	-98.(r5),r1
+	inc	-98.(r5)
+	asl	r1
+	add	-500.(r5),r1
+	mov	(r1),(r0)
+	br	1b
+3:
+	mov	-100.(r5),r0
+	inc	-100.(r5)
+	asl	r0
+	add	-706.(r5),r0
+	mov	$crt0,(r0)
+	mov	-100.(r5),r0
+	inc	-100.(r5)
+	asl	r0
+	add	-706.(r5),r0
+	mov	$libc,(r0)
+	mov	-100.(r5),r0
+	inc	-100.(r5)
+	asl	r0
+	add	-706.(r5),r0
+	clr	(r0)
+	mov	-706.(r5),-(sp)
+	mov	$ldexec,-(sp)
+	jsr	pc, at callsys
+	cmp	(sp)+,(sp)+
+
+cleanup:
+	jsr	pc, at doclean
+	jmp	return
+
+/ cleanup routine
+doclean:
+	mov	tmp1,-(sp)
+	jsr	pc, at unlink
+	tst	(sp)+
+	mov	tmp2,-(sp)
+	jsr	pc, at unlink
+	tst	(sp)+
+	mov	tmp3,-(sp)
+	jsr	pc, at unlink
+	tst	(sp)+
+	mov	tmp0,-(sp)
+	jsr	pc, at unlink
+	tst	(sp)+
+	jsr	pc, at flush
+	jmp	return
+
+/ getsuf - get filename suffix
+getsuf:
+	mov	r5,-(sp)
+	mov	sp,r5
+	add	$-6,sp
+	clr	-4(r5)
+	mov	4(r5),-2(r5)
+1:
+	mov	4(r5),r0
+	inc	4(r5)
+	movb	(r0),r0
+	movb	r0,-6(r5)
+	beq	2f
+	cmpb	-6(r5),$'/
+	bne	3f
+	clr	-4(r5)
+	br	1b
+3:
+	inc	-4(r5)
+	br	1b
+2:
+	sub	$3,4(r5)
+	cmp	-4(r5),$8.
+	bgt	notok
+	cmp	-4(r5),$2
+	ble	notok
+	mov	4(r5),r0
+	inc	4(r5)
+	cmpb	(r0),$'.
+	bne	notok
+	cmpb	@4(r5),$'c
+	bne	notok
+	mov	$'c,r0
+	jmp	return
+notok:
+	clr	r0
+	jmp	return
+
+/ setsuf - set filename suffix
+setsuf:
+	mov	r5,-(sp)
+	mov	sp,r5
+	tst	-(sp)
+	mov	4(r5),-2(r5)
+1:
+	mov	4(r5),r0
+	inc	4(r5)
+	movb	(r0),r0
+	beq	2f
+	br	1b
+2:
+	mov	4(r5),r0
+	movb	$'o,-2(r0)
+	mov	-2(r5),r0
+	jmp	return
+
+/ copy - copy string to temp space
+copy:
+	mov	r5,-(sp)
+	mov	sp,r5
+	tst	-(sp)
+	mov	tsp,-2(r5)
+1:
+	mov	tsp,r0
+	inc	tsp
+	mov	4(r5),r1
+	inc	4(r5)
+	movb	(r1),r1
+	movb	r1,(r0)
+	mov	r1,r0
+	beq	2f
+	br	1b
+2:
+	mov	-2(r5),r0
+	jmp	return
+
+/ nodup - check for duplicate entry
+nodup:
+	mov	r5,-(sp)
+	mov	sp,r5
+	add	$-6,sp
+	mov	6(r5),-2(r5)
+	mov	4(r5),r0
+	add	$2,4(r5)
+	mov	(r0),r0
+	mov	r0,-6(r5)
+	beq	notfound
+1:
+	mov	-2(r5),6(r5)
+	mov	6(r5),r0
+	inc	6(r5)
+	movb	(r0),r0
+	movb	r0,-4(r5)
+	beq	endstr
+	mov	-6(r5),r0
+	inc	-6(r5)
+	cmpb	(r0),-4(r5)
+	beq	1b
+	jmp	@nomatch
+endstr:
+	mov	-6(r5),r0
+	inc	-6(r5)
+	tstb	(r0)
+	bne	nextent
+	clr	r0
+	jmp	return
+nextent:
+	jmp	1b
+notfound:
+	mov	$1,r0
+	jmp	return
+
+/ exit routine
+dexit:
+	mov	2(sp),r0
+	sys	exit
+	sys	fork
+	br	1f
+	bec	1f
+1:
+	clr	r0
+	rts	pc
+
+/ fork system call wrapper
+dofork:
+	mov	2(sp),r0
+	beq	1f
+	bit	$1,r0
+	beq	2f
+1:
+	bic	$1,r0
+	mov	r0,0f
+	sys	intr; 0:.=.+2
+	rts	pc
+2:
+	mov	r5,savedr5
+	mov	r0,savedret
+	sys	intr; child
+	rts	pc
+
+child:
+	mov	savedr5,r5
+	jmp	@savedret
+
+/ link system call wrapper
+dolink:
+	mov	2(sp),0f
+	mov	4(sp),0f+2
+	clr	r0
+	sys	link; 0:.=.+2; .=.+2
+	adc	r0
+	rts	pc
+
+/ open system call wrapper
+doopen:
+	mov	2(sp),0f
+	mov	4(sp),0f+2
+	sys	open; 0:.=.+2; 0:.=.+2
+	bec	1f
+	mov	$-1,r0
+1:
+	rts	pc
+
+/ wait system call wrapper
+dowait:
+	clr	hession
+	sys	wait
+	bec	1f
+	mov	$-1,r0
+	rts	pc
+1:
+	cmp	@0(sp),0f
+	bne	1f
+	mov	hession, at 2(sp)
+1:
+	rts	pc
+
+0:	tst	(sp)+
+
+/ execv system call wrapper
+doexec:
+	mov	r1,-(sp)
+	mov	(r5)+,r1
+	mov	r0,0f
+	sys	exec; 0:.=.+2; 17
+	bcs	error
+	mov	r0,(r1)+
+	clr	(r1)+
+	clr	(r1)+
+	mov	(sp)+,r1
+	rts	r5
+error:
+	mov	$-1,(r1)+
+	mov	(sp)+,r1
+	sec
+	rts	r5
+
+/ putw - buffered write
+putw:
+	mov	(r5),0f
+	mov	(r5)+,0f+2
+	mov	r0,-(sp)
+	jsr	r5,putc; 0:.=.+2
+	mov	(sp)+,r0
+	swab	r0
+	jsr	r5,putc; 0:.=.+2
+	rts	r5
+
+/ putc - write single char
+putc:
+	mov	r1,-(sp)
+	mov	(r5)+,r1
+	dec	2(r1)
+	bge	1f
+	mov	r0,-(sp)
+	jsr	pc,flush
+	mov	(sp)+,r0
+	br	putc+4
+1:
+	movb	r0, at 4(r1)
+	inc	4(r1)
+	mov	(sp)+,r1
+	rts	r5
+
+/ flush output buffer
+flsbuf:
+	mov	r0,-(sp)
+	mov	r1,-(sp)
+	mov	(r5)+,r1
+	jsr	pc,doflush
+	mov	(sp)+,r1
+	mov	(sp)+,r0
+	rts	r5
+
+doflush:
+	mov	r1,r0
+	add	$6,r0
+	mov	r0,-(sp)
+	mov	r0,0f
+	neg	r0
+	add	4(r1),r0
+	ble	1f
+	mov	r0,0f+2
+	mov	(r1),r0
+	sys	write; 0:.=.+2; 0:.=.+2
+1:
+	mov	(sp)+,4(r1)
+	mov	$512.,2(r1)
+	rts	pc
+
+/ return subroutine
+return:
+	mov	r5,sp
+	mov	(sp)+,r5
+	rts	pc
+
+/ callsys - call subprocess
+callsys:
+	mov	r5,-(sp)
+	mov	sp,r5
+	tst	-(sp)
+	mov	4(r5),(r4)
+	mov	6(r5),hession
+	mov	(r4),r0
+	mov	r0,-2(r5)
+	beq	1f
+	mov	6(r5),-(sp)
+	mov	-2(r5),-(sp)
+	jsr	pc, at printf
+	cmp	(sp)+,(sp)+
+1:
+	mov	4(r5),(r4)
+	mov	6(r5),hession
+	mov	hession,r0
+	mov	r0,-(sp)
+	add	$'0,(sp)
+	jsr	pc, at putchar
+	tst	(sp)+
+	jmp	return
+
+/ printf wrapper
+dprintf:
+	mov	r5,-(sp)
+	mov	sp,r5
+	add	$-10.,sp
+	mov	r5,r0
+	add	$6,r0
+	mov	r0,-4(r5)
+1:
+	mov	4(r5),r0
+	inc	4(r5)
+	movb	(r0),r0
+	mov	r0,-10.(r5)
+	cmp	r0,$'%
+	beq	format
+	tst	-10.(r5)
+	beq	2f
+	jmp	3f
+2:
+	jmp	return
+3:
+	mov	-10.(r5),-(sp)
+	jsr	pc, at putchar
+	tst	(sp)+
+	jmp	1b
+
+format:
+	mov	-4(r5),r0
+	add	$2,-4(r5)
+	mov	(r0),-6(r5)
+	mov	4(r5),r0
+	inc	4(r5)
+	movb	(r0),r0
+	mov	r0,-10.(r5)
+	jsr	pc,fmttbl
+	bne	1b
+	jmp	return
+
+fmttbl:
+	mov	@(sp)+,r1
+	cmp	(r1)+,r0
+	beq	1f
+	tst	(r1)+
+	bne	fmttbl+2
+	mov	-4(r1),r7
+1:
+	mov	(r1)+,r0
+	beq	1b
+	mov	r0,r7
+
+/ printf format table
+formtab:
+	'd; prdec
+	'o; proct
+	'c; prchar
+	's; prstr
+	0; retfmt
+
+prdec:
+	mov	-6(r5),r0
+	neg	r0
+	mov	r0,-6(r5)
+	tst	-6(r5)
+	blt	1f
+	jmp	prdec2
+1:
+	cmpb	-10.(r5),$'o
+	beq	2f
+	jmp	3f
+2:
+	mov	$octerr,-(sp)
+	jsr	pc, at printf
+	tst	(sp)+
+	jmp	4f
+3:
+	mov	$decerr,-(sp)
+	jsr	pc, at printf
+	tst	(sp)+
+4:
+	jmp	@finis
+prdec2:
+	mov	$'-,-(sp)
+	jsr	pc, at putchar
+	tst	(sp)+
+	cmpb	-10.(r5),$'o
+	bne	1f
+	mov	$8.,-(sp)
+	br	2f
+1:
+	mov	$10.,-(sp)
+2:
+	mov	-6(r5),-(sp)
+	jsr	pc, at prnumb
+	cmp	(sp)+,(sp)+
+	jmp	@finis
+
+proct:
+	mov	-6(r5),-(sp)
+	jsr	pc, at putchar
+	tst	(sp)+
+	jmp	@finis
+
+prchar:
+	mov	-6(r5),-2(r5)
+1:
+	mov	-2(r5),r0
+	inc	-2(r5)
+	movb	(r0),r0
+	mov	r0,-10.(r5)
+	beq	2f
+	mov	-10.(r5),-(sp)
+	jsr	pc, at putchar
+	tst	(sp)+
+	jmp	1b
+2:
+	jmp	@finis
+
+prstr:
+	mov	$'%,-(sp)
+	jsr	pc, at putchar
+	tst	(sp)+
+	dec	4(r5)
+	mov	-4(r5),r0
+	sub	$2,-4(r5)
+	jmp	@finis
+
+retfmt:
+	jmp	return
+
+/ finis - return to caller
+finis:
+	mov	2(sp),r0
+	tst	nproc
+	bne	1f
+	mov	$1,nproc
+1:
+	jsr	r5,putc; fout
+	movb	3(sp),r0
+	beq	1f
+	jsr	r5,putc; fout
+1:
+	cmp	nproc,$1
+	bne	1f
+	jsr	r5,flsbuf; fout
+1:
+	mov	2(sp),r0
+	rts	pc
+
+/ data
+tmpfn:	</tmp/ctm0a\0>
+	.even
+	<%s:\n\0>
+	.even
+c0:	<c0\0>
+	.even
+c0path:	</usr/lib/c0\0>
+	.even
+c1:	<c1\0>
+	.even
+c1path:	</usr/lib/c1\0>
+	.even
+as:	<as\0>
+	.even
+asflag:	<-\0>
+	.even
+aspath:	</bin/as\0>
+	.even
+oext:	<.o\0>
+	.even
+sext:	<.s\0>
+	.even
+crt0:	</usr/lib/crt0.o\0>
+	.even
+libc:	<-lc\0>
+	.even
+ldpath:	</bin/ld\0>
+	.even
+ld:	<ld\0>
+	.even
+ldexec:	</bin/ld\0>
+	.even
+
+mvmsg:	<move failed: %s\n\0>
+	.even
+cmsg:	<%s:\n\0>
+	.even
+cantfnd: <Can't find %s\n\0>
+	.even
+tryagn:	<Try again\n\0>
+	.even
+fatalerr: <Fatal error in %s\n\0>
+	.even
+octerr:	<-o\0>
+	.even
+decerr:	<-d\0>
+	.even
+
+nproc:	0
+fout:	1
+	1000
+	l1
+	0
+	0
+	0
+
+l1:	.=.+512.
+l2:	.=.+512.
+l3:	.=.+512.
+l4:	.=.+512.
+
+.bss
+savedr5: .=.+2
+savedret: .=.+2
+tmp0:	.=.+2
+tmp1:	.=.+2
+tmp2:	.=.+2
+tmp3:	.=.+2
+tsp:	.=.+2
+hession: .=.+4
+
+/ EAE register
+mq = 177304
diff --git a/cmd/db.s b/cmd/db.s
new file mode 100644
index 0000000..74db80b
--- /dev/null
+++ b/cmd/db.s
@@ -0,0 +1,793 @@
+/ db -- debugger
+
+	br	start
+header:
+	7742
+	0
+	0
+brkpt:
+	254
+	0
+
+start:
+	sys	break; 0
+	mov	sp,r5
+	mov	(r5)+,r4
+	tst	(r5)+
+	cmp	r4,$2
+	blt	1f
+	mov	(r5),coession
+	mov	(r5),coression
+	mov	(r5)+,objfil
+1:
+	cmp	r4,$2
+	beq	1f
+	mov	(r5)+,objfil
+1:
+	sys	open; coession:..; 0
+	bes	nocore
+	mov	r0,cession
+	clr	objsw
+	sys	open; coression:..; 1
+	bes	nocore
+	mov	r0,objsw
+	sys	open; objfil:..; 0
+	bec	1f
+	br	nocore
+1:
+	mov	r0,r1
+	sys	read; ohdr; 14.
+	cmp	ohdr,cession
+	bne	1f
+	mov	ohdr+6.,0f
+	mov	r1,r0
+	sys	seek; 0:..; 0
+	mov	ohdr+4,r2
+	cmp	r2,$7376
+	bcs	2f
+	mov	$7376,r2
+2:
+	mov	r2,0f
+	mov	r1,r0
+	sys	read; syms; 0:..
+	add	$syms,r2
+	mov	r2,symend
+	mov	r2,0f
+	sys	break; 0:..
+	mov	r1,r0
+	sys	close
+1:
+	mov	sp,savsp
+	sys	exit
+prompt:
+	clr	errflg
+	jsr	pc,expr
+	jsr	pc,getlin
+	tst	errflg
+	bne	1f
+	mov	$1,count
+	cmpb	r0,$',
+	bne	2f
+	movb	(r4)+,r0
+	mov	dot,-(sp)
+	mov	val,-(sp)
+	mov	savdot,-(sp)
+	jsr	pc,getlin
+	mov	dot,count
+	mov	(sp)+,savdot
+	mov	(sp)+,val
+	mov	(sp)+,dot
+	tst	errflg
+	bne	1f
+2:
+	jsr	pc,command
+	tst	errflg
+	beq	prompt
+1:
+	mov	savsp,sp
+	jsr	r5,prstr; <?\n>; -1
+ploop:
+	jsr	r5,prstr
+		<File not found.\n>
+		-1
+	sys	exit
+
+expr:
+	mov	$inbuf,r4
+	mov	cession,r0
+	sys	read; inbuf; 1
+	cmp	$1,r0
+	blt	1f
+	mov	objsw,r0
+	jsr	r5,cmdch
+		acmd
+	movb	r0,(r4)+
+	br	expr
+1:
+acmd:
+	<?\0>; goline
+	</\0>; slash
+	<\n\0>; newlin
+	<=\0>; equal
+	<!\0>; shell
+	<'\0>; squote
+	<"\0>; dquote
+	<$\0>; dollar
+	<\\\0>; bkslash
+	<:\0>; colon
+	<^\0>; caret
+	<&\0>; ampersnd
+	<`\0>; bquote
+	<%\0>; percent
+	-1; 0
+
+getbuf:
+	movb	r0,(r4)+
+	cmp	r0,$'\n
+	beq	1f
+	mov	cession,r0
+	sys	read; inbuf; 1
+	bes	nocore
+	tst	r0
+	beq	2f
+	cmp	inbuf,$'\n
+	beq	1f
+	inc	errflg
+1:
+	mov	$inbuf,r4
+	rts	pc
+
+cmdch:
+	mov	(r5)+,r1
+1:
+	cmp	r0,(r1)+
+	bne	2f
+	tst	(sp)+
+	jmp	@0(r1)
+2:
+	tst	(r1)+
+	bne	1b
+	rts	r5
+
+getlin:
+	mov	$'+,numsign
+	clr	dot
+	clr	val
+	clr	savtyp
+	clr	savdot
+1:
+	movb	(r4)+,r0
+	cmp	r0,$'0
+	blt	2f
+	cmp	r0,$'7
+	ble	octal
+	cmp	r0,$'a
+	blt	2f
+	cmp	r0,$'z
+	bgt	2f
+	jmp	symbol
+2:
+	cmp	r0,$'A
+	blt	3f
+	cmp	r0,$'Z
+	ble	symbol
+3:
+	jsr	r5,cmdch
+		numops
+	tstb	-(r4)
+	rts	pc
+
+numops:
+	<+\0>; plus
+	<-\0>; minus
+	< \0>; space
+	<.\0>; period
+	<_\0>; uscore
+	-1; 0
+
+plus:
+	inc	savdot
+	cmp	numsign,$'+
+	beq	1f
+	sub	savtyp,dot
+	cmp	regtyp,$3
+	bne	2f
+	mov	$1,val
+	br	3f
+1:
+	add	savtyp,dot
+	bis	regtyp,val
+2:
+	mov	$'+,numsign
+	br	getlin+4
+
+octal:
+	clr	r1
+1:
+	asl	r1
+	asl	r1
+	asl	r1
+	bic	$177770,r0
+	bis	r0,r1
+	movb	(r4)+,r0
+	cmp	r0,$'0
+	bcs	2f
+	cmp	r0,$'7
+	blos	1b
+2:
+	mov	$1,regtyp
+	cmpb	-(r4),$'r
+	bne	3f
+	mov	$3,regtyp
+	inc	r4
+	br	4f
+3:
+	cmpb	(r4),$'b
+	bne	4f
+	asl	r1
+	inc	r4
+4:
+	mov	r1,savtyp
+	br	plus
+
+symbol:
+	tstb	-(r4)
+	mov	$namebuf,r1
+	clr	(r1)+
+	clr	(r1)+
+	clr	(r1)+
+	clr	(r1)
+	mov	$namebuf,r1
+	mov	$8.,-(sp)
+	br	2f
+1:
+	tstb	(r4)+
+	cmpb	(r4),$'.
+	beq	2f
+	cmpb	(r4),$'0
+	bcs	3f
+	cmpb	(r4),$'9
+	blos	2f
+	cmpb	(r4),$'A
+	bcs	3f
+	cmpb	(r4),$'Z
+	bhi	4f
+	bisb	$40,(r4)
+	br	2f
+4:
+	cmpb	(r4),$'_
+	beq	2f
+	cmpb	(r4),$'a
+	bcs	3f
+	cmpb	(r4),$'z
+	bhi	3f
+2:
+	dec	(sp)
+	ble	1b
+	movb	(r4),(r1)+
+	br	1b
+3:
+	tst	(sp)+
+	jsr	pc,lookup
+	jmp	plus
+
+command:
+	mov	r0,numsign
+	jmp	getlin+4
+
+nocore:
+	inc	errflg
+	rts	pc
+
+goline:
+	</\0>; slash
+	<`\0>; prmem
+	<?\0>; prmem2
+	<\n\0>; newlin
+	<^\0>; prreg
+	<=\0>; prval
+	<:\0>; brkset
+	<!\0>; shell
+	<'\0>; prchr
+	<"\0>; prstr2
+	<$\0>; prsym
+	<&\0>; prloc
+	<%\0>; prmod
+	-1; 0
+
+/ memory display
+prmem:
+	jsr	r5,memloc
+		rdcore
+	tst	savdot
+	beq	1f
+	bic	$177770,r0
+	asl	r0
+	asl	r0
+	mov	regtab(r0),0f
+	mov	regtab+2(r0),0f+2
+	jsr	r5,prstr; 0:..; 0:..
+		<\n>
+		-1
+1:
+	jsr	r5,memloc
+		rdcore
+	tst	savdot
+	beq	2f
+	sub	baseadr,r0
+	mov	r0,curoff
+	mov	$regtab,r5
+	mov	(r5)+,0f
+	beq	2f
+	jsr	r5,prstr; 0:..; </\0>
+		-1
+	cmp	dot,$'sp
+	bne	3f
+	mov	curoff,r0
+	add	baseadr,r0
+	br	4f
+3:
+	jsr	r5,memloc
+		pval
+4:
+	mov	r0,r3
+	jsr	pc,prhex
+	jsr	pc,prval2
+	mov	r3,r0
+	jsr	pc,disasm
+	jsr	pc,prtype
+	jsr	pc,prcr
+	add	$2,curoff
+	br	1b
+2:
+	rts	pc
+
+/ system call table
+syscall:
+	<??\0\0\0\0>
+	<indir\0>
+	<exit\0\0>
+	<fork\0\0>
+	<read\0\0>; 2
+	<write\0>; 2
+	<open\0\0>; 2
+	<close\0>; 0
+	<wait\0\0>; 0
+	<creat\0>; 2
+	<link\0\0>; 2
+	<unlink\0>; 1
+	<exec\0\0>; 2
+	<chdir\0>; 1
+	<time\0\0>; 0
+	<mknod\0>; 1
+	<chmod\0>; 2
+	<chown\0>; 2
+	<break\0>; 1
+	<stat\0\0>; 2
+	<seek\0\0>; 2
+	<tell\0\0>; 2
+	<21.\0\0\0>
+	<22.\0\0\0>
+	<setuid\0>
+	<getuid\0>
+	<setitime\0>
+	<quit\0\0>; 1
+	<intr\0\0>; 1
+	<fstat\0>; 1
+	<emt.\0\0>
+	<smdat\0>; 1
+
+prreg:
+	jsr	r5,prlocs
+		regdsp
+	rts	pc
+
+regdsp:
+	<mq\0>; mq
+	<ac\0>; ac
+	<r5\0>; savr5
+	<r4\0>; savr4
+	<r3\0>; savr3
+	<r2\0>; savr2
+	<r1\0>; savr1
+	<r0\0>; savr0
+	<pc\0>; savpc
+	<ps\0>; savps
+	<sp\0>; 0
+	0
+
+clrbss:
+	clr	adtyp
+	mov	$2,prsmod
+	jsr	r5,memloc
+		rdbyte
+	rts	pc
+
+rdbyte:
+	mov	r0,savdot
+	jsr	pc,disasm
+	jsr	pc,prtype
+	jsr	pc,prcr
+	rts	pc
+
+prlocs:
+	jsr	pc,memloc
+	mov	dot,r0
+	mov	val,r1
+	jsr	r5,prbyte
+	jsr	pc,prcr
+	rts	r5
+
+prbyte:
+	jsr	r5,memloc
+		rdbyte
+	rts	r5
+
+memloc:
+	tst	savdot
+	bne	1f
+	mov	dot,savtyp
+	mov	val,savdot
+1:
+	rts	pc
+
+/ output routines
+prhex:
+	mov	r0,mq
+1:
+	clr	ac
+	mov	$10.,div
+	mov	ac,-(sp)
+	tst	mq
+	beq	2f
+	jsr	pc,1b
+2:
+	mov	(sp)+,mq
+	add	$'0,mq
+	mov	outfd,r0
+	sys	write; mq; 1
+	rts	pc
+
+prtype:
+	jsr	pc,prspc
+	mov	dot,r0
+	jsr	pc,prhex
+	jsr	pc,prcr
+	rts	pc
+
+prcr:
+	jsr	r5,prstr; <\n>; -1
+	rts	pc
+
+prspc:
+	jsr	r5,prstr; < >; -1
+	rts	pc
+
+prstar:
+	jsr	r5,prstr; <*>; -1
+	rts	pc
+
+prlpar:
+	jsr	r5,prstr; <(>; -1
+	rts	pc
+
+prrpar:
+	jsr	r5,prstr; <)>; -1
+	rts	pc
+
+prbcom:
+	jsr	r5,prstr; <b>; -1
+	rts	pc
+
+prcomma:
+	jsr	r5,prstr; <,>; -1
+	rts	pc
+
+prstr:
+	mov	(r5)+,0f
+	bpl	1f
+	rts	r5
+1:
+	mov	$1,r0
+	sys	write; 0:..; 2
+	br	prstr
+
+wrbyte:
+	mov	@(r5)+,0f
+	mov	cession,r0
+	sys	seek; 0:..; 0
+	mov	cession,r0
+	tst	adtyp
+	beq	1f
+	mov	$1,0f+2
+	br	2f
+1:
+	mov	$2,0f+2
+2:
+	sys	write; 0:..; 0:..
+	bes	1b
+	rts	r5
+
+lookup:
+	cmp	namebuf,$'.
+	bne	1f
+	mov	dot,savtyp
+	mov	val,regtyp
+	rts	pc
+1:
+	tst	namebuf+2
+	bne	2f
+	mov	$regtab,r0
+3:
+	mov	(r0)+,r1
+	beq	2f
+	cmp	r1,namebuf
+	bne	3b
+	sub	$regtab+2,r0
+	mov	$1,regtyp
+	cmp	r0,$26.
+	bne	4f
+	mov	$40004,savtyp
+	rts	pc
+4:
+	mov	r0,r2
+	jsr	r5,memloc
+		rdcore
+	tst	savdot
+	bne	5f
+	sub	baseadr,r0
+	add	r2,r0
+	mov	r0,savtyp
+5:
+	rts	pc
+2:
+	mov	$syms,r1
+	mov	$namebuf,r0
+6:
+	cmp	(r0)+,(r1)+
+	bne	7f
+	cmp	(r0)+,(r1)+
+	bne	8f
+	cmp	(r0)+,(r1)+
+	bne	9f
+	cmp	(r0)+,(r1)+
+	bne	10f
+	mov	(r1)+,regtyp
+	bic	$40,regtyp
+	mov	(r1)+,savtyp
+	rts	pc
+7:
+	tst	(r1)+
+8:
+	tst	(r1)+
+9:
+	tst	(r1)+
+10:
+	cmp	(r1)+,(r1)+
+	cmp	r1,symend
+	bcs	2b
+	inc	errflg
+	clr	savtyp
+	clr	regtyp
+	rts	pc
+
+findsym:
+	mov	$syms,r5
+	mov	r1,-(sp)
+	clr	r2
+	mov	$77777,r3
+1:
+	cmp	r5,symend
+	bcc	2f
+	cmp	(r5),$'.
+	beq	3f
+	mov	10.(r5),-(sp)
+	bic	$40,(sp)
+	cmp	(sp)+,(sp)
+	bne	3f
+	mov	12.(r5),r1
+	sub	r0,r1
+	bge	4f
+	neg	r1
+4:
+	cmp	r1,r3
+	bge	3f
+	mov	r1,r3
+	mov	r5,r2
+3:
+	add	$14.,r5
+	br	1b
+2:
+	tst	(sp)+
+	rts	pc
+
+rdcore:
+	mov	@(r5)+,0f
+	mov	cession,r0
+	sys	seek; 0:..; 0
+	bes	1f
+	mov	(r5)+,0f
+	mov	cession,r0
+	tst	adtyp
+	beq	2f
+	mov	$1,0f+2
+	br	3f
+2:
+	mov	$2,0f+2
+3:
+	sys	read; 0:..; 0:..
+	bes	1f
+	mov	curoff,r0
+	rts	r5
+1:
+	tst	(r5)+
+	inc	errflg
+	rts	r5
+
+disasm:
+	mov	r0,r3
+	mov	r3,-(sp)
+	bic	$177767,(sp)
+	bic	$177770,r0
+	cmp	r0,$7
+	beq	2f
+	mov	r3,r0
+	asr	r0
+	asr	r0
+	asr	r0
+	bic	$177771,r0
+	jmp	@optab(r0)
+
+optab:
+	op0
+	op1
+	op2; op3
+op0:
+	tst	(sp)
+	beq	1f
+	jsr	pc,prstar
+1:
+	jsr	pc,prmode
+	tst	(sp)+
+	beq	3f
+	jsr	pc,prlpar
+	br	4f
+3:
+	jsr	pc,prrpar
+4:
+	rts	pc
+
+op1:
+	tst	(sp)+
+	beq	1f
+	jsr	pc,prspc
+1:
+	jsr	pc,prstar
+	jsr	r5,prstr; <-(>; -1
+	br	4b
+
+op2:
+	tst	(sp)+
+	beq	1f
+	jsr	pc,prspc
+1:
+	jsr	r5,prstr; <(>; -1
+	jsr	pc,prmode
+	jsr	r5,prstr; <)+>; -1
+	br	4b
+
+op3:
+	tst	(sp)+
+	beq	1f
+	jsr	pc,prspc
+1:
+	jsr	pc,rdoff
+	jsr	pc,prhex
+	jsr	pc,prtype
+	jsr	pc,prstar
+	jsr	pc,prlpar
+	br	4b
+
+2:
+	mov	r3,r0
+	bit	$20,r3
+	beq	op0-4
+	tst	(sp)+
+	beq	1f
+	jsr	pc,prspc
+1:
+	bit	$40,r3
+	bne	3f
+	jsr	r5,prstr; <$>; -1
+	jsr	pc,rdoff
+	jsr	pc,prhex
+	jsr	pc,prtype
+	br	4f
+3:
+	jsr	pc,rdoff
+	add	$2,r0
+	add	r1,r0
+	mov	$3,r1
+	jsr	pc,prtype
+	br	4f
+4:
+	tst	(r5)+
+	clr	r0
+	rts	r5
+
+prmode:
+	mov	$2,r0
+	rts	r5
+
+rdoff:
+	mov	@(r5)+,r1
+	add	$2,r1
+	mov	r1,curoff
+	jsr	r5,memloc
+		pval
+	rts	pc
+
+pval:
+	jsr	r5,memloc
+		rdbyte
+	rts	r5
+
+/ register display
+regtab:
+	<r0>; <r1>
+	<r2>; <r3>
+	<r4>; <r5>
+	<sp>; <pc>
+
+/ data area
+coession:
+	<core\0>
+coression:
+	<.out\0>
+	.even
+objfil:
+	syms
+	0
+	0
+	0
+	0
+
+baseadr: 0
+curoff:	0
+cession: 0
+objsw:	0
+outfd:	1
+savsp:	0
+errflg:	0
+count:	0
+numsign: 0
+dot:	0
+val:	0
+savdot:	0
+savtyp:	0
+regtyp:	0
+adtyp:	0
+prsmod:	2
+symend:	0
+
+/ EAE registers
+ac:	.=.+2
+mq:	.=.+2
+
+/ saved registers
+savr0:	.=.+2
+savr1:	.=.+2
+savr2:	.=.+2
+savr3:	.=.+2
+savr4:	.=.+2
+savr5:	.=.+2
+savpc:	.=.+2
+savps:	.=.+2
+
+/ header
+ohdr:	.=.+16.
+
+/ buffers
+namebuf: .=.+8.
+inbuf:	.=.+512.
+syms:
diff --git a/cmd/dc.s b/cmd/dc.s
new file mode 100644
index 0000000..4b728a7
--- /dev/null
+++ b/cmd/dc.s
@@ -0,0 +1,508 @@
+/ dc -- desk calculator (arbitrary precision)
+
+	br	start
+	mov	@-(r2), at 0(sp)
+	0
+	0
+	0
+
+start:
+	mov	$heap,r5
+	clr	r0
+	jsr	pc,alloc
+	mov	r1,numbuf
+	clr	r0
+	jsr	pc,alloc
+	mov	r1,numbuf2
+	clr	r0
+	jsr	pc,alloc
+	mov	r1,numbuf3
+	clr	r0
+	jsr	pc,alloc
+	mov	r1,tempbuf
+	mov	sp,savesp
+	jsr	pc,getc
+
+/ main command loop
+loop:
+	mov	$cmdtbl,r1
+1:
+	tst	(r1)+
+	beq	2f
+	cmp	r0,(r1)+
+	bne	1b
+	jmp	@-4(r1)
+2:
+	sys	exit
+	movb	r0,savech
+	jsr	pc,number
+	jsr	pc,push
+	br	loop
+
+/ commands
+quit:
+	sys	fork
+	br	1f
+	mov	$1,r0
+	sys	write; qmsg; 2
+1:
+	br	loop
+
+qcmd:
+	sys	stat; 0:filnam; statbuf
+	br	1f
+	bic	r1, at statbuf
+	4
+	bic	r1, at 0(sp)
+
+filnam:	</etc/msh\0>
+	.even
+	cmp	r5,$heap
+	bne	1f
+	jmp	empty
+
+1:
+	clr	r0
+	jsr	pc,alloc
+	mov	-2(r5),r0
+	jsr	pc,copy
+	jsr	pc,push
+	br	loop
+
+/ digits 0-9
+digit:
+	jsr	pc,getc
+	bcs	loop
+	jsr	pc,pushdig
+	br	digit
+
+/ load/store
+loadcmd:
+	jsr	pc,getc
+	cmp	r5,$heap
+	bne	1f
+	movb	$'s,savech
+	jmp	empty
+1:
+	cmpb	r0,$200
+	blo	2f
+	jmp	badch
+2:
+	asl	r0
+	mov	regs(r0),r1
+	beq	1f
+	jsr	pc,pushdig
+1:
+	jsr	pc,getc
+	mov	r1,regs(r0)
+	br	loop
+
+storecmd:
+	jsr	pc,getc
+	cmp	r0,$200
+	blo	1f
+	jmp	badch
+1:
+	asl	r0
+	mov	regs(r0),r1
+	bne	1f
+	jmp	empty
+1:
+	mov	r1,-(sp)
+	clr	r0
+	jsr	pc,alloc
+	mov	(sp)+,r0
+	jsr	pc,copy
+	jsr	pc,push
+	br	loop
+
+/ arithmetic operations
+addcmd:
+	mov	$addnum,r0
+	jsr	pc,binop
+	jmp	loop
+
+subcmd:
+	mov	$subnum,r0
+	jsr	pc,binop
+	tst	wflag
+	beq	1f
+	jsr	pc,getc
+	mov	r1,r3
+	mov	tempbuf,r2
+	jsr	pc,wrcmd
+	jsr	pc,push
+	mov	r3,r1
+	jsr	pc,pushdig
+1:
+	jmp	loop
+
+mulcmd:
+	mov	$mulnum,r0
+	jsr	pc,binop
+	jmp	loop
+
+divcmd:
+	tst	wflag
+	beq	1f
+	mov	r2,-(sp)
+	mov	tempbuf,r2
+	jsr	pc,divmod
+	mov	r1,-(sp)
+	mov	r3,r1
+	jsr	pc,pushdig
+	mov	(sp)+,r3
+	mov	(sp)+,r2
+1:
+	jsr	pc,wrcmd
+	rts	pc
+
+binop:
+	jsr	pc,getc
+	bec	1f
+	jmp	empty
+1:
+	mov	r1,r2
+	jsr	pc,getc
+	bec	1f
+	jmp	empty
+1:
+	mov	r1,r3
+	jsr	pc,(r0)
+	jsr	pc,push
+	mov	r2,r1
+	jsr	pc,pushdig
+	mov	r3,r1
+	jsr	pc,pushdig
+	rts	pc
+
+/ input/output radix
+ibasecmd:
+	jsr	pc,getc
+	bec	1f
+	jmp	empty
+1:
+	mov	0(r1),r0
+	sub	4(r1),r0
+	cmp	r0,$1
+	blos	1f
+	jmp	empty
+1:
+	jsr	pc,pop
+	jsr	pc,getval
+	mov	r0,ibase
+	mov	r0,r2
+	jsr	pc,pushdig
+	mov	tempbuf,r1
+	jsr	pc,pop2
+	clr	r0
+	cmp	r2,$2
+	blo	1f
+	jsr	pc,mulby10
+	sub	$2,r2
+	br	1b
+1:
+	mov	$1,r0
+	cmp	r2,$1
+	blo	1f
+	mov	$10.,r0
+1:
+	jsr	pc,mulby10
+	jmp	loop
+
+obasecmd:
+	jsr	pc,getc
+	bcs	empty2
+	mov	r1,-(sp)
+	cmp	stkptr,$stkbot
+	beq	1f
+	mov	@stkptr,r1
+	cmp	2(r1),0(r1)
+	bne	2f
+	jsr	pc,pushdig
+	br	3f
+1:
+	add	$2,stkptr
+	cmp	stkptr,$stktop
+	bhis	1f
+2:
+	mov	(sp)+,r1
+	mov	r1, at stkptr
+	jsr	pc,pop
+	jmp	loop
+1:
+	mov	$1,r0
+	sys	write; nestmsg; 15.
+	sys	exit
+
+nestmsg: <Nesting depth.\n\0>
+	.even
+stkptr:	stkbot
+	0; 0; 0; 0; 0; 0; 0; 0
+	0; 0; 0; 0; 0; 0; 0; 0
+	0; 0; 0; 0; 0; 0; 0; 0
+	0; 0; 0; 0; 0; 0; 0; 0
+	0; 0; 0; 0; 0; 0; 0; 0
+	0; 0; 0; 0; 0; 0; 0; 0
+stktop:
+
+empty2:
+	movb	r0,savech+2
+	mov	$1,r0
+	sys	write; savech; 17
+	sys	exit
+savech:	0
+
+/ print command
+printcmd:
+	jsr	pc,getc
+	bcs	empty
+	mov	r1,-(sp)
+	clr	r0
+	jsr	pc,alloc
+	mov	(sp)+,r0
+	jsr	pc,copy
+	jsr	pc,print
+	mov	r1,-(sp)
+	jsr	pc,getc
+	mov	(sp)+,r1
+	jsr	pc,pushdig
+	rts	pc
+
+/ duplicate top of stack
+dupcmd:
+	jsr	pc,getc
+	bec	1f
+	jmp	empty
+1:
+	mov	r1,-(sp)
+	jsr	pc,getc
+	bec	1f
+	jmp	empty
+1:
+	mov	r1,r2
+	mov	(sp)+,r3
+	jsr	pc,dupit
+	jsr	pc,push
+	mov	r3,r1
+	jsr	pc,pushdig
+	mov	r2,r1
+	jsr	pc,pushdig
+	jmp	loop
+
+/ clear stack
+clearcmd:
+	mov	$heap,r5
+	jmp	loop
+
+/ exchange top two
+exchcmd:
+	jsr	pc,getc
+	bec	1f
+	jmp	empty
+1:
+	mov	r1,r2
+	jsr	pc,getc
+	bec	1f
+	jmp	empty
+1:
+	mov	r1,r3
+	mov	r2,r1
+	jsr	pc,push
+	mov	r3,r1
+	jsr	pc,push
+	jmp	loop
+
+empty:
+	jmp	loop
+
+badch:
+	jmp	loop
+
+/ read character
+getc:
+	cmp	r5,$heap
+	beq	1f
+	mov	-(r5),r1
+	cmp	2(r1),0(r1)
+	beq	1f
+	movb	@2(r1),r0
+	inc	2(r1)
+	clc
+	rts	pc
+1:
+	tstb	savech
+	beq	2f
+	movb	savech,r0
+	clrb	savech
+	clc
+	rts	pc
+2:
+	sys	read; chbuf; 1
+	bes	3f
+	tst	r0
+	beq	3f
+	movb	chbuf,r0
+	clc
+	rts	pc
+3:
+	sec
+	rts	pc
+
+/ push to stack
+push:
+	mov	r1,(r5)+
+	rts	pc
+
+/ pop from stack
+pop:
+	mov	-(r5),r1
+	rts	pc
+
+/ allocate memory
+alloc:
+	mov	r0,r1
+	add	$8.,r1
+	add	heaptop,r1
+	cmp	r1,$stktop
+	bhi	1f
+	mov	heaptop,r1
+	add	r0,heaptop
+	add	$8.,heaptop
+	clr	(r1)+
+	mov	r1,r0
+	mov	r0,(r1)+
+	mov	r0,(r1)+
+	clr	(r1)+
+	rts	pc
+1:
+	mov	$1,r0
+	sys	write; memerr; 12.
+	sys	exit
+
+memerr:	<Out of mem\n\0>
+	.even
+
+/ copy number
+copy:
+	mov	r0,r3
+	mov	r1,r2
+1:
+	cmp	(r2),(r3)+
+	bhi	2f
+	movb	(r2)+,(r3)+
+	br	1b
+2:
+	rts	pc
+
+/ print number
+print:
+	mov	r1,-(sp)
+	mov	obase,r2
+	tst	(r1)
+	bpl	1f
+	mov	$'-,r0
+	jsr	pc,putc
+	neg	(r1)
+1:
+	mov	(r1),r3
+	beq	3f
+	jsr	pc,div10
+	mov	r0,-(sp)
+	jsr	pc,print+6
+	mov	(sp)+,r0
+	add	$'0,r0
+	jsr	pc,putc
+	br	2f
+3:
+	mov	$'0,r0
+	jsr	pc,putc
+2:
+	mov	(sp)+,r1
+	rts	pc
+
+/ read number
+number:
+	clr	r2
+1:
+	movb	savech,r0
+	beq	2f
+	clrb	savech
+	br	3f
+2:
+	sys	read; chbuf; 1
+	tst	r0
+	beq	4f
+	movb	chbuf,r0
+3:
+	cmpb	r0,$'0
+	blo	4f
+	cmpb	r0,$'9
+	bhi	4f
+	sub	$'0,r0
+	jsr	pc,mulby10
+	add	r0,r2
+	br	1b
+4:
+	movb	r0,savech
+	mov	r2,r0
+	rts	pc
+
+/ multiply by 10
+mulby10:
+	asl	r2
+	mov	r2,-(sp)
+	asl	r2
+	asl	r2
+	add	(sp)+,r2
+	rts	pc
+
+/ get value
+getval:
+	mov	(r1),r0
+	rts	pc
+
+/ output character
+putc:
+	movb	r0,chbuf
+	mov	$1,r0
+	sys	write; chbuf; 1
+	rts	pc
+
+/ command dispatch table
+cmdtbl:
+	'q; quit
+	'+; addcmd
+	'-; subcmd
+	'*; mulcmd
+	'/; divcmd
+	'p; printcmd
+	'c; clearcmd
+	'd; dupcmd
+	'f; exchcmd
+	'i; ibasecmd
+	'o; obasecmd
+	'l; loadcmd
+	's; storecmd
+	' ; loop
+	'\n; loop
+	0
+
+qmsg:	<?\n\0>
+	.even
+
+.bss
+chbuf:	.=.+2
+numbuf:	.=.+2
+numbuf2: .=.+2
+numbuf3: .=.+2
+tempbuf: .=.+2
+savesp:	.=.+2
+ibase:	.=.+2
+obase:	.=.+2
+wflag:	.=.+2
+heaptop: .=.+2
+regs:	.=.+512.
+statbuf: .=.+36.
+stkbot:	.=.+128.
+heap:
diff --git a/cmd/ds.s b/cmd/ds.s
new file mode 100644
index 0000000..edb9b8c
--- /dev/null
+++ b/cmd/ds.s
@@ -0,0 +1,267 @@
+/ ds -- show disk space summary
+
+	mov	$1,r0
+	sys	write; header; 2
+	clr	outfd
+	sys	seek; 0:..; 0
+	cmp	(sp)+,$2
+	blt	1f
+	sys	creat; fname; 17
+	bes	error
+	mov	r0,outfd
+	tst	(sp)+
+	mov	(sp)+,0f
+1:
+	mov	$buf,r4
+	jsr	r5,descend
+	cmp	r4,$buf
+	beq	2f
+	jsr	pc,flush
+	br	1b
+2:
+	mov	$1,r0
+	sys	write; header+1; 3
+	mov	outfd,r0
+	beq	done
+	sys	close
+	sys	open; fname; 0
+	bec	1f
+	br	error
+1:
+	mov	r0,tmpfd
+	br	done
+
+error:
+	mov	$1,r0
+	sys	write; errmsg; 5
+	sys	exit
+
+done:
+	tst	outfd
+	beq	1f
+	sys	creat; 0:..; 17
+	bec	1f
+	br	error
+1:
+	sys	open; dfile; 0
+	bes	error
+	mov	r0,dfd
+	mov	$41.,r5
+	jsr	pc,getblk
+	tst	nused
+	beq	loop
+	mov	outfd,r0
+	beq	loop
+	sys	write; header-1; 1
+	mov	outfd,r0
+	mov	r5,r1
+	jsr	r5,prnum; <-\0>
+	mov	outfd,r0
+	mov	nused,r1
+	jsr	r5,prnum; <\n\0>
+
+loop:
+	mov	$syms,r4
+	clr	r3
+1:
+	cmp	r4,symend
+	bcc	2f
+	cmp	(r4)+,r5
+	bne	3f
+	inc	r3
+	tst	outfd
+	beq	3f
+	mov	(r4),0f
+	mov	tmpfd,r0
+	sys	seek; 0:..; 0
+	mov	tmpfd,r0
+	sys	read; name; 1
+	mov	tmpfd,r0
+	sys	read; name+1; 0:..
+	mov	0b-4,0f
+	mov	outfd,r0
+	sys	write; name+1; 0:..
+	mov	outfd,r0
+	sys	write; header-1; 1
+3:
+	tst	(r4)+
+	br	1b
+2:
+	cmp	r3,nused
+	beq	4f
+	mov	r5,r0
+	mov	$1,r0
+	mov	r5,r1
+	jsr	r5,prnum; <-\0>
+	mov	$1,r0
+	mov	r3,r1
+	jsr	r5,prnum; < \0>
+	mov	$1,r0
+	sys	write; header+2; 5
+4:
+	inc	r5
+	cmp	r5,$2777
+	blt	loop+4
+	sys	unlink; fname
+	sys	exit
+
+addsym:
+	mov	symend,r0
+	mov	inode,(r0)+
+	mov	nameloc,(r0)+
+	mov	r0,symend
+	mov	$name,r0
+1:
+	tstb	(r0)+
+	bne	1b
+	sub	$name+1,r0
+	mov	r0,-(sp)
+	jsr	pc,flush
+	mov	$name,r1
+2:
+	movb	(r1)+,r0
+	jsr	pc,flush
+	dec	(sp)
+	bgt	2b
+	tst	(sp)+
+	rts	r5
+
+descend:
+	sys	stat; name; stbuf
+	bes	error
+	cmp	stbuf+4,$50
+	bgt	1f
+	rts	r5
+1:
+	jsr	r5,addsym
+	bit	$40000,stbuf+6
+	beq	1b-2
+	mov	$name,r0
+1:
+	tstb	(r0)+
+	bne	1b
+	dec	r0
+	mov	r0,r1
+	cmpb	-(r0),$'.
+	bne	2f
+	cmpb	-(r0),$'/
+	beq	1b-2
+	cmpb	(r0),$'.
+	bne	2f
+	cmpb	-(r0),$'/
+	beq	1b-2
+2:
+	mov	r1,-(sp)
+	sys	open; name; 0
+	bes	error
+	mov	r0,-(sp)
+3:
+	mov	(sp),r0
+	sys	read; dirent; 16.
+	bes	4f
+	tst	r0
+	beq	4f
+	tst	dirent
+	beq	3b
+	mov	$dirent+2,r0
+	mov	2(sp),r1
+	cmpb	-1(r1),$'/
+	beq	5f
+	movb	$'/,(r1)+
+5:
+	movb	(r0)+,(r1)+
+	bne	5b
+	jsr	r5,descend
+	br	3b
+4:
+	mov	(sp)+,r0
+	sys	close
+	mov	(sp)+,r0
+	clrb	(r0)
+	rts	r5
+
+getblk:
+	mov	r5,r0
+	add	$31.,r0
+	mov	r0,-(sp)
+	asr	r0
+	asr	r0
+	asr	r0
+	asr	r0
+	cmp	r0,blkno
+	beq	1f
+	mov	r0,blkno
+	mov	dfd,r0
+	sys	seek; 0:..; 0
+	mov	dfd,r0
+	sys	read; dblk; 512.
+1:
+	bic	$177760,(sp)
+	mov	(sp)+,num
+	mov	$5,lsh
+	mov	num,r0
+	tst	dblk(r0)
+	blt	2f
+	clr	nused
+	rts	pc
+2:
+	movb	dblk+2(r0),nused
+	rts	pc
+
+flush:
+	inc	nameloc
+	tst	outfd
+	beq	1f
+	movb	r0,(r4)+
+	cmp	r4,$buf+512.
+	blo	1f
+	mov	outfd,r0
+	sys	write; buf; 512.
+	mov	$buf,r4
+1:
+	rts	pc
+
+prnum:
+	mov	r0,fd
+	mov	r1,num
+	jsr	pc,1f
+	mov	(r5)+,ch
+	mov	fd,r0
+	sys	write; ch; 1
+	rts	r5
+1:
+	clr	num-2
+	mov	$10.,div
+	mov	num-2,-(sp)
+	tst	num
+	beq	2f
+	jsr	pc,1b
+2:
+	mov	(sp)+,ch
+	add	$'0,ch
+	mov	fd,r0
+	sys	write; ch; 1
+	rts	pc
+
+symend:	syms
+nameloc: .=.+2
+header:
+	</tmp/dstmpi ****/dev/rp0/\0>
+	.even
+blkno:	.=.+2
+outfd:	.=.+2
+tmpfd:	.=.+2
+dfd:	.=.+2
+fd:	.=.+2
+ch:	.=.+2
+num:	.=.+4
+nused:	.=.+2
+inode:	.=.+2
+stbuf:	.=.+40.
+dirent:	.=.+16.
+dblk:	.=.+512.
+fname:	.=.+64.
+name:	.=.+512.
+buf:	.=.+512.
+syms:
+errmsg:	<err?\n>
diff --git a/cmd/du.s b/cmd/du.s
new file mode 100644
index 0000000..e7080c0
--- /dev/null
+++ b/cmd/du.s
@@ -0,0 +1,187 @@
+/ du -- disk usage
+
+	mov	(sp)+,r5
+	tst	(sp)+
+	dec	r5
+	bgt	1f
+	tstb	dot
+	beq	2f
+	sys	exit
+2:
+	mov	$dot,r0
+	br	3f
+1:
+	mov	(sp)+,r0
+	cmpb	(r0),$'-
+	bne	doarg
+	cmpb	1(r0),$'a
+	bne	4f
+	inc	aflag
+	br	2b
+4:
+	cmpb	1(r0),$'s
+	bne	2b
+	dec	aflag
+	br	2b
+
+doarg:
+	mov	$name,r1
+1:
+	movb	(r0)+,(r1)+
+	bne	1b
+	dec	r1
+	clr	level
+	clr	total
+	jsr	pc,dodir
+	tst	aflag
+	bpl	2b
+	jsr	r5,prsize
+	br	2b
+
+dodir:
+	sys	stat; name; stbuf
+	bec	1f
+	cmp	stbuf+4,$50
+	bgt	2f
+1:
+	clr	r4
+	rts	pc
+2:
+	mov	total,r0
+	mov	$dirlist,r2
+	mov	stbuf+4,r3
+	tst	r0
+	beq	3f
+1:
+	cmp	r3,(r2)+
+	bne	2f
+	clr	r4
+	jsr	r5,prpath
+	rts	pc
+2:
+	dec	r0
+	br	1b
+3:
+	mov	r3,(r2)+
+	inc	total
+	bit	$40000,stbuf+6
+	bne	isdir
+	jsr	pc,blocks
+	jsr	r5,prpath
+	rts	pc
+
+isdir:
+	jsr	pc,blocks
+	mov	r4,r3
+	sys	open; name; 0
+	bec	1f
+	rts	pc
+1:
+	mov	r0,-(sp)
+	mov	r1,-(sp)
+	mov	2(sp),r0
+	sys	read; dirent; 16.
+	bes	done
+	tst	r0
+	beq	done
+	tst	dirent
+	beq	1b
+	cmp	dirent+2,$'.
+	beq	1b
+	cmp	dirent+2,$'.+<'.<<8>
+	bne	2f
+	tst	dirent+4
+	beq	1b
+2:
+	mov	$dirent+2,r2
+	mov	(sp),r1
+	movb	$'/,(r1)+
+	cmpb	-2(r1),$'/
+	bne	3f
+	dec	r1
+3:
+	movb	(r2)+,(r1)+
+	bne	3b
+	dec	r1
+	mov	r3,-(sp)
+	jsr	pc,dodir
+	mov	r4,r3
+	add	(sp)+,r3
+	br	1b
+
+done:
+	mov	(sp)+,r1
+	clrb	(r1)
+	mov	(sp)+,r0
+	sys	close
+	mov	r3,r4
+	tst	aflag
+	bmi	1f
+	jsr	r5,prsize
+1:
+	rts	pc
+
+prpath:
+	tst	aflag
+	bgt	prsize
+	rts	r5
+
+prsize:
+	jsr	pc,decml
+	mov	$'\t,r0
+	jsr	pc,putc
+	mov	$name,r2
+1:
+	movb	(r2)+,r0
+	beq	2f
+	jsr	pc,putc
+	br	1b
+2:
+	mov	$'\n,r0
+	jsr	pc,putc
+	rts	r5
+
+blocks:
+	mov	stbuf+12.,mq
+	add	$777,mq
+	clr	ac
+	mov	$-9,lsh
+	cmp	mq,$8.
+	blo	1f
+	mov	mq,-(sp)
+	add	$377,mq
+	mov	$-8,lsh
+	add	(sp)+,mq
+1:
+	mov	mq,r4
+	rts	pc
+
+decml:
+	mov	r4,mq
+	clr	ac
+	mov	$10.,div
+	mov	ac,-(sp)
+	tst	mq
+	beq	1f
+	jsr	pc,decml
+1:
+	mov	(sp)+,r0
+	add	$'0,r0
+	jsr	pc,putc
+	rts	pc
+
+putc:
+	mov	r0,ch
+	mov	$1,r0
+	sys	write; ch; 1
+	rts	pc
+
+ch:	.=.+2
+dot:	<.\0>
+name:	.=.+512.
+total:	.=.+2
+level:	.=.+2
+aflag:	.=.+2
+stbuf:	.=.+40.
+dirent:	.=.+16.
+dirlist: .=.+200.
diff --git a/cmd/ed.s b/cmd/ed.s
new file mode 100644
index 0000000..ef3617d
--- /dev/null
+++ b/cmd/ed.s
@@ -0,0 +1,437 @@
+/ ed -- line editor
+
+	cmpb	@2(sp),$'-
+	bne	1f
+	inc	proteflag
+	jsr	r5,gfile; <oops\0>
+1:
+	sys	break; 0
+
+start:
+	clr	peteflag
+	clr	stession
+	clr	sflag
+	mov	sp,savsp
+	mov	sp,r4
+	cmp	(r4)+,$1
+	blos	command
+	tst	(r4)+
+	mov	(r4)+,r4
+	mov	$tfname,r1
+	mov	$sfname,r2
+1:
+	movb	(r4),(r2)+
+	movb	(r4)+,(r1)+
+	bne	1b
+	mov	linebp,zero+2
+	mov	$'\n,loc2
+	jmp	rfile
+
+command:
+	jmp	commands
+
+	.bss
+buf:	.=.+256.
+linebuf: .=.+128.
+expbuf: .=.+128.
+rhsbuf:	.=.+64.
+savedfile: .=.+64.
+file:	.=.+64.
+	.even
+
+commands:
+	jsr	r5,gfile; <oops\0>
+	clr	qcount
+	jsr	r5,getfile
+	mov	loc2,a1
+	jsr	r5,getchar
+	cmp	r1,$'\n
+	bne	commands
+	mov	savsp,sp
+	tst	qflag
+	beq	1f
+	clr	qflag
+	mov	zero,a2
+	mov	zero,dot
+	jmp	rfile
+1:
+	tst	pflag
+	beq	2f
+	tstb	@prompt
+	bne	2f+6
+	mov	zero,r4
+	tst	(r4)+
+	cmp	r4,linebp
+	bhi	2f+4
+	bit	$1,(r4)
+	beq	2b-2
+	dec	(r4)
+	mov	r4,zero
+	mov	$tfname,prompt
+	br	2f+6
+2:
+	jsr	r5,getfile
+1:
+	tst	proteflag
+	beq	2f
+	mov	$1,r0
+	sys	write; schar; 1
+2:
+	clr	peteflag
+	jsr	r5,getline
+	br	com2
+
+nexta:
+	inc	a1
+nextl:
+	mov	a1,a2
+	mov	a1,dot
+	jsr	r5,getchar
+	br	com3
+com3:	<;\0>
+com3b:	<,\0>
+com3c:	0
+
+nextdot:
+	cmp	a1,linebp
+	bhi	comerr
+	mov	a1,zero
+	jsr	r5,getline
+	br	comerr
+
+nextdot2:
+	mov	dot,a2
+	br	nextl
+
+com2:
+	jsr	r5,getchar
+com3:
+	br	com2
+
+comlst:
+	<a\0>; comapp
+	<c\0>; comchg
+	<d\0>; comdel
+	<e\0>; comedit
+	<f\0>; comfile
+	<g\0>; comglob
+	<i\0>; comins
+	<k\0>; commark
+	<l\0>; comlist
+	<m\0>; commove
+	<n\0>; comnum
+	<p\0>; comprnt
+	<q\0>; comquit
+	<r\0>; comread
+	<s\0>; comsub
+	<v\0>; comv
+	<w\0>; comwrit
+	<=\0>; comeq
+	<!\0>; comexcl
+	<\n\0>; comnl
+	0
+
+comapp:
+	jsr	r5,newaddr
+	jsr	r5,setdot
+	br	append
+
+comchg:
+	jsr	r5,newaddr
+	jsr	r5,setdot
+	jsr	r5,delete
+	mov	dot,a2
+	br	1f
+
+comdel:
+	jsr	r5,newaddr
+	jsr	r5,setdot
+	jsr	r5,delete
+	mov	dot,zero
+	cmp	dot,linebp
+	blos	done
+	mov	linebp,zero
+	br	done
+
+comedit:
+	jsr	r5,newaddr
+	jsr	r5,setdot
+	mov	a2,zero
+	sub	$2,dot
+	cmp	dot,zero
+	bcc	1f
+	mov	dot,zero
+1:
+	jsr	r5,append
+	br	1b
+done:
+	jmp	commands
+
+comerr:
+	jmp	comerr
+
+comprnt:
+	jsr	r5,setdot2
+	jsr	r5,setdot
+	jsr	r5,print
+	sys	exit
+
+comquit:
+	jsr	r5,setdot2
+	jsr	r5,getchar
+	cmp	r1,$'
+	bne	comerr
+	mov	$linebuf+512.,r0
+1:
+	clr	(r0)+
+	cmp	r0,$sfname+512.
+	bne	1b
+	jsr	r5,print
+	jsr	r5,execute
+
+comread:
+	jsr	r5,setdot2
+	jsr	r5,setdot
+rfile:
+	mov	$sfname,r4
+1:
+	jsr	r5,getchar
+	cmp	r1,$'\n
+	beq	2f
+	cmp	r1,$'
+	beq	1b
+	movb	r1,(r4)+
+	br	1b
+2:
+	clrb	(r4)
+	sys	open; sfname; 0
+	bes	comerr
+	mov	r0,fin
+	clr	ninbuf
+3:
+	jsr	r5,getc
+	bes	4f
+	jsr	r5,putline
+	br	3b
+4:
+	mov	fin,r0
+	sys	close
+	br	done
+
+comsub:
+	jsr	r5,setdot2
+	jsr	r5,setdot
+	jsr	r5,compile
+	jsr	r5,getchar
+	jsr	r5,getchar
+1:
+	jsr	r5,getchar
+	cmpb	r1,delim
+	beq	2f
+	cmp	r1,$'\n
+	beq	comerr
+	movb	r1,(r3)+
+	br	1b
+2:
+	clrb	(r3)+
+	jsr	r5,getchar
+	jsr	r5,dosub
+	br	done
+
+comwrit:
+	jsr	r5,setdot2
+	jsr	r5,setdot
+wfile:
+	mov	$sfname,r4
+1:
+	jsr	r5,getchar
+	cmp	r1,$'\n
+	beq	2f
+	cmp	r1,$'
+	beq	1b
+	movb	r1,(r4)+
+	br	1b
+2:
+	clrb	(r4)
+	sys	creat; sfname; 17
+	bes	comerr
+	mov	r0,fout
+	mov	a2,r4
+3:
+	cmp	r4,dot
+	bhi	4f
+	jsr	r5,getline2
+	jsr	r5,putfile
+	tst	(r4)+
+	br	3b
+4:
+	mov	fout,r0
+	sys	close
+	br	done
+
+append:
+	jsr	r5,getline
+	tst	(sp)+
+	tstb	linebuf
+	beq	1f
+	cmpb	linebuf,$'.
+	bne	2f
+	tstb	linebuf+1
+	bne	2f
+1:
+	rts	r5
+2:
+	jsr	r5,putline
+	br	append
+
+delete:
+	mov	a2,r4
+	mov	dot,r3
+1:
+	cmp	r3,linebp
+	bhi	2f
+	mov	(r3)+,(r4)+
+	br	1b
+2:
+	mov	r4,linebp
+	rts	r5
+
+print:
+	mov	a2,r4
+1:
+	cmp	r4,dot
+	bhi	2f
+	jsr	r5,getline2
+	jsr	r5,putstr
+	tst	(r4)+
+	br	1b
+2:
+	rts	r5
+
+getline:
+	mov	$linebuf,r3
+1:
+	jsr	r5,getc
+	bes	2f
+	movb	r0,(r3)+
+	cmpb	r0,$'\n
+	bne	1b
+	clrb	-(r3)
+	rts	r5
+2:
+	clrb	(r3)
+	rts	r5
+
+getc:
+	dec	ninbuf
+	bge	1f
+	mov	fin,r0
+	sys	read; inbuf; 512.
+	bes	2f
+	tst	r0
+	beq	2f
+	dec	r0
+	mov	r0,ninbuf
+	mov	$inbuf,inp
+1:
+	clr	r0
+	bisb	@inp,r0
+	inc	inp
+	rts	r5
+2:
+	sec
+	rts	r5
+
+putline:
+	mov	linebp,r4
+	mov	$linebuf,r3
+1:
+	movb	(r3)+,(r4)+
+	bne	1b
+	mov	r4,linebp
+	rts	r5
+
+putstr:
+	mov	$linebuf,r3
+	mov	$1,r0
+1:
+	tstb	(r3)
+	beq	2f
+	sys	write; linebuf; 1
+	inc	r3
+	br	1b
+2:
+	sys	write; nl; 1
+	rts	r5
+
+putfile:
+	mov	fout,r0
+	mov	$linebuf,r3
+1:
+	tstb	(r3)+
+	bne	1b
+	sub	$linebuf,r3
+	mov	r3,0f
+	mov	fout,r0
+	sys	write; linebuf; 0:..
+	mov	fout,r0
+	sys	write; nl; 1
+	rts	r5
+
+getchar:
+	jsr	r5,getc
+	mov	r0,r1
+	rts	r5
+
+gfile:
+	mov	(r5)+,0f
+	mov	$1,r0
+	sys	write; 0:..; 1
+	emt	3
+
+compile:
+	rts	r5
+
+execute:
+	rts	r5
+
+dosub:
+	rts	r5
+
+setdot:
+	rts	r5
+
+setdot2:
+	rts	r5
+
+newaddr:
+	rts	r5
+
+getfile:
+	rts	r5
+
+schar:	<*\0>
+nl:	<\n>
+prompt:	.=.+2
+delim:	.=.+2
+fin:	.=.+2
+fout:	.=.+2
+ninbuf:	.=.+2
+inp:	.=.+2
+a1:	.=.+2
+a2:	.=.+2
+dot:	.=.+2
+zero:	.=.+4
+linebp:	.=.+2
+loc2:	.=.+2
+savsp:	.=.+2
+proteflag: .=.+2
+pflag:	.=.+2
+qflag:	.=.+2
+qcount:	.=.+2
+sflag:	.=.+2
+peteflag: .=.+2
+stession: .=.+2
+tfname:	.=.+64.
+sfname:	.=.+64.
+inbuf:	.=.+512.
diff --git a/cmd/fc.s b/cmd/fc.s
new file mode 100644
index 0000000..8900836
--- /dev/null
+++ b/cmd/fc.s
@@ -0,0 +1,309 @@
+/ fc -- FORTRAN compiler driver
+/ NOTE: This is B-compiled code; shown as reconstructed assembly
+
+	br	start
+	inc	@(r2)+
+	0
+	0
+	0
+	0
+	0
+	0
+
+start:
+	mov	$mq,r3
+	mov	sp,r0
+	mov	(sp),-(sp)
+	tst	(r0)+
+	mov	r0,2(sp)
+	mov	60.,(sp)
+	mov	$brt,r5
+	jmp	@(r5)+
+
+brt:
+	fmain
+	0
+
+fmain:
+	blib
+	sys	exit
+
+blib:
+	fcall
+	dofc1
+	fcall
+	doas
+	fcall
+	dold
+	fcall
+	domove
+	bproc
+	bprint
+	bexit
+	bint
+	bchar
+	bputc
+	bgetc
+	bopen
+	bclose
+	bcopy
+	bscopy
+	bprintf
+	0
+
+/ B runtime routines
+bexit:
+	mov	2(sp),r0
+	sys	exit
+
+dofc1:
+	jsr	r5,prname
+	jsr	pc,callsub
+	mov	r0,status
+	tst	status
+	bne	err
+	rts	pc
+
+doas:
+	jsr	r5,prname
+	jsr	pc,callsub
+	mov	r0,status
+	tst	status
+	bne	err
+	rts	pc
+
+dold:
+	jsr	r5,prname
+	jsr	pc,callsub
+	mov	r0,status
+	tst	status
+	bne	err
+	rts	pc
+
+domove:
+	jsr	r5,prname
+	mov	r0,status
+	tst	status
+	bne	moveerr
+	rts	pc
+
+prname:
+	mov	$1,r0
+	sys	write; namebuf; 0:..
+	rts	r5
+
+callsub:
+	sys	fork
+	br	child
+	bec	parent
+child:
+	sys	exec; argv; argp
+	jsr	r5,mesg; <Can't find \0>; .even
+	mov	$1,r0
+	sys	write; argv; 0:..
+	jsr	r5,mesg; <\n\0>; .even
+	sys	exit
+parent:
+	sys	wait
+	rts	pc
+
+moveerr:
+	jsr	r5,mesg; <move failed: \0>; .even
+	mov	$1,r0
+	sys	write; namebuf; 0:..
+	jsr	r5,mesg; <\n\0>; .even
+	rts	pc
+
+err:
+	jsr	r5,mesg; <Try again\n\0>; .even
+	sys	exit
+
+mesg:
+	movb	(r5)+,ch
+	beq	1f
+	mov	$1,r0
+	sys	write; ch; 1
+	br	mesg
+1:
+	inc	r5
+	bic	$1,r5
+	rts	r5
+
+bprintf:
+	mov	r5,-(sp)
+	mov	sp,r5
+	add	$6,r5
+	mov	(r5)+,r4
+1:
+	movb	(r4)+,r0
+	beq	2f
+	cmpb	r0,$'%
+	beq	3f
+	jsr	pc,bputc
+	br	1b
+2:
+	mov	(sp)+,r5
+	rts	pc
+3:
+	movb	(r4)+,r0
+	cmpb	r0,$'s
+	bne	4f
+	mov	(r5)+,r1
+	jsr	pc,bprstr
+	br	1b
+4:
+	cmpb	r0,$'d
+	bne	1b
+	mov	(r5)+,r0
+	jsr	pc,bprdec
+	br	1b
+
+bprstr:
+	movb	(r1)+,r0
+	beq	1f
+	jsr	pc,bputc
+	br	bprstr
+1:
+	rts	pc
+
+bprdec:
+	mov	r0,mq
+	clr	ac
+	mov	$10.,div
+	mov	ac,-(sp)
+	tst	mq
+	beq	1f
+	jsr	pc,bprdec
+1:
+	add	$'0,(sp)
+	mov	(sp)+,ch
+	mov	$1,r0
+	sys	write; ch; 1
+	rts	pc
+
+bputc:
+	movb	r0,ch
+	mov	$1,r0
+	sys	write; ch; 1
+	rts	pc
+
+bgetc:
+	clr	r0
+	sys	read; ch; 1
+	movb	ch,r0
+	rts	pc
+
+bopen:
+	mov	2(sp),0f
+	mov	4(sp),0f+2
+	sys	open; 0:..; 0:..
+	bec	1f
+	mov	$-1,r0
+1:
+	rts	pc
+
+bclose:
+	mov	2(sp),r0
+	sys	close
+	rts	pc
+
+bcopy:
+	mov	r1,-(sp)
+1:
+	movb	(r2)+,(r1)+
+	bne	1b
+	mov	(sp)+,r1
+	rts	pc
+
+bscopy:
+	mov	r1,-(sp)
+	mov	r2,-(sp)
+	mov	4(sp),r1
+	mov	6(sp),r2
+1:
+	movb	(r1)+,(r2)+
+	bne	1b
+	mov	(sp)+,r2
+	mov	(sp)+,r1
+	rts	pc
+
+bint:
+	mov	r0,mq
+	clr	ac
+	rts	pc
+
+bchar:
+	movb	r0,r0
+	rts	pc
+
+bprint:
+	movb	(r0)+,r1
+	beq	1f
+	movb	r1,ch
+	mov	$1,r0
+	sys	write; ch; 1
+	br	bprint
+1:
+	rts	pc
+
+fcall:
+	jsr	pc,@(r5)+
+	rts	r5
+
+bproc:
+	tst	(r5)+
+	rts	r5
+
+/ data
+fmsg:	<%s:\n\0>
+	.even
+fcname:	<fc\0>
+	.even
+fc1path: </usr/fort/fc1\0>
+	.even
+asname:	<as\0>
+	.even
+asflag:	<-\0>
+	.even
+tmpf:	<f.tmp1\0>
+	.even
+aspath:	</bin/as\0>
+	.even
+aout:	<a.out\0>
+	.even
+aout2:	<a.out\0>
+	.even
+movmsg:	<move failed: %s\n\0>
+	.even
+tmpf2:	<f.tmp1\0>
+	.even
+ldname:	<ld\0>
+	.even
+fr0:	</usr/lib/fr0.o\0>
+	.even
+lflag:	<-lf\0>
+	.even
+filib:	</usr/lib/filib.a\0>
+	.even
+lflag2:	<-l\0>
+	.even
+ldpath:	</bin/ld\0>
+	.even
+cantmsg: <Can't find %s\n\0>
+	.even
+trymsg:	<Try again\n\0>
+	.even
+
+.bss
+ch:	.=.+2
+mq:	.=.+2
+ac:	.=.+2
+status:	.=.+2
+namebuf: .=.+64.
+argv:	.=.+64.
+argp:	.=.+32.
+
+/ EAE registers
+div = 177300
+ac = 177302
+mq = 177304
diff --git a/cmd/find.s b/cmd/find.s
new file mode 100644
index 0000000..b8fe2ae
--- /dev/null
+++ b/cmd/find.s
@@ -0,0 +1,140 @@
+/ find -- find files
+
+	mov	(sp)+,argc
+	tst	(sp)+
+	mov	sp,argv
+	mov	from,to
+	mov	from+2,to+2
+	mov	$path,r5
+	jsr	pc,descend
+	sys	exit
+
+prname:
+	mov	r4,-(sp)
+	mov	(r5)+,r4
+1:
+	movb	(r4)+,r0
+	beq	2f
+	jsr	pc,putc
+	br	1b
+2:
+	mov	$'\n,r0
+	jsr	pc,putc
+	mov	(sp)+,r4
+	rts	r5
+
+putc:
+	mov	r0,ch
+	mov	$1,r0
+	sys	write; ch; 1
+	rts	pc
+
+descend:
+	mov	r4,-(sp)
+	mov	r5,-(sp)
+	cmp	r5,$path-1
+	beq	1f
+	clrb	-(r5)
+1:
+	sys	open; path; 0
+	bes	done
+	mov	r0,fin
+	movb	$'/,(r5)+
+2:
+	mov	fin,r0
+	sys	read; dirent; 16.
+	bes	done
+	tst	r0
+	beq	done
+	tst	dirent
+	beq	2b
+	mov	(sp),r5
+	mov	$dirent+2,r3
+	mov	$8.,r2
+1:
+	movb	(r3)+,(r5)+
+	dec	r2
+	bne	1b
+	clrb	(r5)
+	mov	argv,r4
+	mov	argc,argcnt
+	mov	(sp),r5
+	mov	(r4),r1
+3:
+	dec	argcnt
+	ble	nomatch
+	mov	$9.,r0
+1:
+	dec	r0
+	beq	2f
+	cmpb	(r1),(r5)+
+	bne	4f
+	tstb	(r1)+
+	bne	1b
+2:
+	jsr	r5,prname; path
+	mov	(r4)+,r0
+	jsr	pc,getnum
+	cmp	r0,dirent
+	bne	3b
+	jsr	r5,prname; path
+	br	3b
+
+4:
+	sys	stat; path; stbuf
+	bit	$40000,stbuf+4
+	beq	2b
+	mov	(sp),r5
+	cmpb	(r5)+,$'.
+	bne	5f
+	tstb	(r5)
+	beq	2b
+	cmpb	(r5)+,$'.
+	bne	5f
+	tstb	(r5)
+	beq	2b
+5:
+	tstb	(r5)+
+	bne	5b
+	mov	fin,-(sp)
+	jsr	pc,descend
+	mov	(sp)+,fin
+	br	2b
+
+done:
+	mov	fin,r0
+	sys	close
+	tst	(sp)+
+	mov	(sp)+,r4
+	rts	pc
+
+getnum:
+	clr	num
+1:
+	movb	(r2)+,r0
+	beq	2f
+	sub	$'0,r0
+	cmp	r0,$9.
+	bhi	3f
+	mov	$10.,mul
+	add	r0,num
+	br	1b
+3:
+	clr	num
+2:
+	mov	num,r0
+	rts	pc
+
+from:	</usr\0>
+	.even
+to:	.=.+4
+
+argc:	.=.+2
+argv:	.=.+2
+argcnt:	.=.+2
+ch:	.=.+2
+fin:	.=.+2
+num:	.=.+2
+dirent:	.=.+16.
+stbuf:	.=.+40.
+path:	.=.+512.
diff --git a/cmd/form.s b/cmd/form.s
new file mode 100644
index 0000000..1430d3a
--- /dev/null
+++ b/cmd/form.s
@@ -0,0 +1,300 @@
+/ form -- form letter generator
+
+	br	start
+	ble	1f
+	0
+	0
+
+	mov	(sp)+,-(sp)
+	0
+
+start:
+	mov	$-1,oession
+	mov	$-1,mession
+	clr	fession
+	mov	(sp)+,r2
+	tst	(sp)+
+	sub	$2,r2
+	bge	1f
+	mov	$letter,-(sp)
+1:
+	mov	(sp)+,fname
+	sys	stat; fmem; stbuf
+	bcc	1f
+	sys	creat; fmem; 017
+	bcc	1f
+	cmpb	$'z,fmem+4
+	beq	memerr
+	incb	fmem+4
+	br	1b
+1:
+	mov	r0,mfd
+	sys	open; fmem; 1
+	bcc	1f
+	sys	creat; fmem; 017
+	bcs	crterr
+1:
+	mov	r0,mession
+	sys	seek; 0; 2
+	sys	open; fmem; 0
+	bes	opnerr
+	mov	r0,oession
+	jmp	main
+
+memerr:
+	mov	$1,r0
+	sys	write; errmsg; 24.
+	sys	exit
+
+crterr:
+	mov	$1,r0
+	sys	write; errmsg2; 24.
+	sys	exit
+
+errmsg:	<cannot open memory file\0>
+errmsg2: <cannot open output file\0>
+fmem:	<forma\0>
+	.even
+fmems:	<form.am\0>
+	.even
+letter:	<letter\0>
+	.even
+
+/ initialized data area
+.=.+512.
+
+/ month table
+month:
+jan:	<CJanuary\0>
+feb:	<February\0>
+mar:	<March\0>
+apr:	<April\0>
+may:	0
+jun:	<June\0>
+jul:	<July\0>
+aug:	<August\0>
+sep:	<September\0>
+oct:	<October\0>
+nov:	<November\0>
+dec:	<December\0>
+	.even
+
+/ main processing
+main:
+	mov	$1,r1
+	jsr	r5,getc; ibuf
+	beq	done
+	cmpb	r0,$'\\
+	bne	1f
+	jsr	pc,doesc
+	br	main
+1:
+	cmpb	r0,$'\n
+	bne	2f
+	jsr	pc,donl
+	br	main
+2:
+	jsr	r5,putc; obuf
+	br	main
+
+done:
+	jsr	r5,flush; obuf
+	sys	exit
+
+donl:
+	jsr	r5,putc; obuf
+	mov	$'\n,r0
+	jsr	r5,putc; obuf
+	rts	pc
+
+doesc:
+	jsr	r5,getc; ibuf
+	beq	escend
+	cmpb	r0,$'\\
+	beq	1f
+	cmpb	r0,$'n
+	beq	donewl
+	cmpb	r0,$'a
+	blt	dolet
+	cmpb	r0,$'z
+	bgt	dolet
+	sub	$'a,r0
+	asl	r0
+	mov	mtab(r0),r0
+	beq	escend
+	jsr	pc,prstr
+	br	escend
+1:
+	mov	$'\\,r0
+	jsr	r5,putc; obuf
+escend:
+	rts	pc
+
+donewl:
+	mov	$'\n,r0
+	jsr	r5,putc; obuf
+	rts	pc
+
+dolet:
+	movb	r0,letbuf
+	mov	$1,r0
+	sys	write; letbuf; 1
+	rts	pc
+
+prstr:
+	mov	r0,r1
+1:
+	movb	(r1)+,r0
+	beq	2f
+	jsr	r5,putc; obuf
+	br	1b
+2:
+	rts	pc
+
+/ input line
+getline:
+	mov	r3,-(sp)
+	mov	$':,r0
+	jsr	r5,putc; obuf
+	mov	$' ,r0
+	jsr	r5,putc; obuf
+	jsr	r5,flush; obuf
+1:
+	movb	r0,(r3)+
+	cmp	r0,$'\n
+	bne	1b
+	jsr	r5,getc; ibuf
+	cmp	r0,$'\n
+	beq	2f
+	movb	r0,(r3)+
+	br	1b
+2:
+	clrb	-1(r3)
+	mov	(sp)+,r3
+	rts	pc
+
+/ buffered I/O
+getc:
+	mov	r1,-(sp)
+	mov	(r5)+,r1
+	mov	2(r1),r0
+	bne	1f
+	mov	r1,r0
+	add	$4,r0
+	mov	r0,0f
+	mov	$256.,-(sp)
+	clr	(r0)+
+	dec	(sp)
+	bne	.-4
+	tst	(sp)+
+	mov	(r1),r0
+	sys	read; 0:..; 512.
+	bes	eof
+	tst	r0
+	beq	eof
+	clr	r0
+1:
+	inc	r0
+	mov	r0,2(r1)
+	cmp	r0,$512.
+	bne	2f
+	clr	2(r1)
+2:
+	add	r1,r0
+	movb	3(r0),r0
+	beq	getc+4
+	mov	(sp)+,r1
+	tst	(r5)
+	bne	3f
+	cmp	(r5)+,(r5)+
+3:
+	rts	r5
+
+eof:
+	mov	(sp)+,r1
+	tst	(r5)+
+	bne	1f
+	rts	r5
+1:
+	jsr	r5,flush; obuf
+	sys	exit
+
+inch:
+	clr	r0
+	sys	read; chbuf; 1
+	bes	1f
+	tst	r0
+	beq	1f
+	movb	chbuf,r0
+	rts	r5
+1:
+	jsr	r5,flush; obuf
+	sys	exit
+
+putc:
+	mov	r0,chbuf
+	mov	$1,r0
+	sys	write; chbuf; 1
+	rts	r5
+
+putc2:
+	mov	r1,-(sp)
+	mov	r0,-(sp)
+	mov	(r5)+,r1
+	tst	(r1)+
+	mov	(r1),r0
+	add	r1,r0
+	movb	(sp)+,2(r0)
+	inc	(r1)
+	cmp	(r1),$512.
+	bge	1f
+	mov	(sp)+,r1
+	rts	r5
+1:
+	mov	(sp)+,r1
+	tst	-(r5)
+
+flush:
+	mov	r1,-(sp)
+	mov	(r5)+,r1
+	mov	(r1)+,r0
+	mov	(r1),0f
+	beq	1f
+	clr	(r1)+
+	mov	r1,0f+2
+	sys	write; 0:..; 0:..
+1:
+	mov	(sp)+,r1
+	rts	r5
+
+ovflerr: <storage overflow\n\0>
+	.even
+
+opnerr:
+	jsr	r5,mesg
+	<cannot open file\0>
+	.even
+	sys	exit
+
+mesg:
+	movb	(r5)+,r0
+	beq	1f
+	jsr	pc,putc
+	br	mesg
+1:
+	inc	r5
+	bic	$1,r5
+	rts	r5
+
+.bss
+fname:	.=.+2
+mfd:	.=.+2
+mession: .=.+2
+oession: .=.+2
+fession: .=.+2
+stbuf:	.=.+36.
+chbuf:	.=.+2
+letbuf:	.=.+2
+ibuf:	.=.+518.
+obuf:	.=.+518.
+mtab:	.=.+52.
diff --git a/cmd/ld.s b/cmd/ld.s
new file mode 100644
index 0000000..6b84ecb
--- /dev/null
+++ b/cmd/ld.s
@@ -0,0 +1,878 @@
+/ ld -- link editor (linker)
+
+	br	start
+	adc	@-(sp)
+	0
+	mov	0(r1),0(r0)
+	0
+	0
+
+start:
+	sys	intr; onerr
+	mov	(sp)+,r0
+	dec	r0
+	bgt	1f
+	sys	exit
+1:
+	mov	r0,argc
+	mov	sp,argv
+	jsr	r5,argscan
+	br	2f
+1:
+	jsr	r5,ldfile
+	br	argscan+6
+2:
+	sys	exec; 0:outfn; 0
+	bec	1f
+	clr	outfd
+	jsr	r5,errout
+		<\n\0>; .even
+	sys	exit
+1:
+	mov	r0,outfd
+	mov	tsize,r1
+	mov	dsize,r2
+	mov	r1,r3
+	add	r2,r3
+	clr	r4
+	mov	$symtab,r5
+1:
+	cmp	r5,symptr
+	bhis	symsdone
+	cmp	10.(r5),$'
+	bne	2f
+	mov	12.(r5),r0
+	beq	2f
+	mov	r4,12.(r5)
+	add	r3,12.(r5)
+	inc	r0
+	bic	$1,r0
+	add	r0,r4
+	mov	$''',10.(r5)
+2:
+	add	$12.,r5
+	br	1b
+
+symsdone:
+	add	r4,bsize
+	mov	$symtab,r5
+1:
+	cmp	r5,symptr
+	bhis	2f
+	cmp	10.(r5),$'#
+	blt	3f
+	beq	4f
+	cmp	10.(r5),$''
+	bne	5f
+	mov	$'$,10.(r5)
+	br	3f
+5:
+	add	r2,12.(r5)
+	add	r4,12.(r5)
+4:
+	add	r1,12.(r5)
+3:
+	add	$12.,r5
+	br	1b
+2:
+	mov	r1,outtxt
+	mov	r3,outdat
+	add	r4,outdat
+	mov	hession+4,hession+2
+	add	symptr,hession+4
+	sub	$symtab,hession+4
+	tst	sflag
+	beq	1f
+	clr	hession+4
+1:
+	jsr	r5,wrhdr
+		outbf; outhdr
+	jsr	r5,wrhdr
+		txtbf; outdat
+	tst	rflag
+	bne	1f
+	jsr	r5,wrhdr
+		rdbf; outrel
+	jsr	r5,wrhdr
+		sdbf; outsym
+1:
+	jsr	r5,wrhdr
+		rtbf; outrel
+	tst	nflag
+	beq	1f
+	tst	errcnt
+	bne	1f
+	mov	(sp)+,symptr
+	cmp	r5,$symlst
+	blos	2f
+	clr	@-(r5)
+	br	1f
+2:
+	tst	(sp)+
+	tst	ession
+	beq	1f
+	add	outtxt,ession
+	tst	errcnt
+	beq	1f
+	jsr	r5,errout
+		err4; .even
+	mov	ession,errcnt
+1:
+	add	hession+2,hession+4
+	mov	bufptr,r0
+	cmp	r0,$symlst
+	bhis	1f
+	jsr	r5,errout
+		err5; .even
+	jmp	onerr
+1:
+	mov	entpt,r1
+	bne	1f
+	mov	@argv,r1
+	cmp	r1,$entry
+	bne	1f
+	movb	libch,r1
+1:
+	mov	r1,(r0)+
+	mov	nflag,(r0)+
+	beq	1f
+	bis	$1,entpt
+1:
+	mov	r0,bufptr
+	jsr	r5,doreloc
+	mov	(sp)+,r5
+	rts	r5
+
+/ link a file
+ldfile:
+	mov	tsize,outtxt
+	mov	outtxt+2,r0
+	add	dsize,r0
+	sub	offset,r0
+	mov	r0,outdat
+	mov	outdat+2,r0
+	add	bsize,r0
+	sub	offset,r0
+	sub	offset+2,r0
+	mov	r0,outbss
+	mov	r5,-(sp)
+	jsr	r5,setup
+		outbf; outhdr
+	mov	$symlst,r5
+	mov	$-1,-(sp)
+	mov	outfd,r1
+	tstb	(r1)+
+	bne	1f
+	cmp	r1,outfd
+	blos	2f
+	cmpb	-(r1),$'/
+	bne	1f
+	tstb	(r1)+
+2:
+	mov	$sysname,r0
+1:
+	movb	(r1)+,(r0)+
+	bne	1f
+	tstb	-(r1)
+1:
+	cmp	r0,$sysname+8.
+	blo	1b
+	mov	$37.,hession
+	mov	outtxt,hession+2
+	tst	sflag
+	bne	1f
+	jsr	r5,wrname
+1:
+	jsr	r5,reloc
+	bvs	done
+	jsr	r5,doreloc
+	inc	(sp)
+	cmp	hession,$'
+	bhis	1f
+	tst	nflag
+	bne	1b
+	add	$12.,hession+2
+	br	1b
+1:
+	jsr	r5,lookup
+	mov	(r4),r0
+	beq	1f
+	cmp	10.(r0),$'
+	bgt	1b
+	cmp	hession,$'
+	ble	3f
+	inc	errcnt
+	br	2f
+1:
+	mov	r4,(r5)+
+	jsr	r5,newsym
+	cmp	hession,$'
+	ble	1b
+3:
+	jsr	r5,rdsymtab
+	mov	(r4),r0
+	mov	hession,10.(r0)
+	mov	hession+2,12.(r0)
+	br	1b
+
+done:
+	tst	endflg
+	beq	1f
+	tst	errcnt
+	bne	1f
+	mov	(sp)+,symptr
+	cmp	r5,$symlst
+	blos	2f
+	clr	@-(r5)
+	br	1f
+2:
+	tst	(sp)+
+1:
+	tst	ession
+	beq	1f
+	add	outtxt,ession
+	tst	errcnt
+	beq	1f
+	jsr	r5,errout
+		err4; .even
+1:
+	mov	ession,errcnt
+	add	hession+2,hession+4
+	mov	bufptr,r0
+	cmp	r0,$symlst
+	bhis	1f
+	jsr	r5,errout
+		err3; .even
+	jmp	onerr
+1:
+	mov	(sp)+,(r5)+
+	mov	(r4),(r5)+
+	br	1b
+
+pass2:
+	mov	r5,symend
+	tst	(sp)+
+	jsr	r5,setup
+		outbf; txtbf
+	jsr	r5,setup
+		sdbf; symhdr
+	mov	tsize,pass2txt
+	jsr	r5,getword
+	br	1f
+2:
+	tst	rflag
+	bne	1f
+	jsr	r5,putw; rdbf
+1:
+	mov	r3,r0
+	jsr	r5,putw; outbf
+	br	2b
+
+	jsr	r5,setup
+		outbf; datbf
+	mov	outdat,r0
+	mov	r0,pass2txt
+	mov	(sp)+,r5
+	jsr	r5,getword
+	br	1f
+2:
+	tst	rflag
+	bne	1f
+	jsr	r5,putw; sdbf
+1:
+	mov	r3,r0
+	jsr	r5,putw; outbf
+	br	2b
+
+	jsr	r5,doreloc
+	rts	r5
+
+/ read word from input buffer
+getword:
+	mov	(r5)+,r1
+	sub	$2,(r1)+
+	bge	1f
+	sev
+	rts	r5
+1:
+	mov	(r1)+,r2
+	cmp	r2,(r1)+
+	bhis	2f
+	mov	(r2)+,r0
+	mov	r2,-4(r1)
+	rts	r5
+2:
+	mov	(r1),0f
+	mov	infd,r0
+	sys	seek; 0:.=.+2; 0
+	add	$512.,(r1)+
+	mov	r1,0f
+	mov	-8.(r1),r0
+	add	$2,r0
+	cmp	r0,$512.
+	ble	1f
+	mov	$512.,r0
+1:
+	mov	r0,0f+2
+	jsr	r5,doread; 0:.=.+2; .=.+2
+	mov	(r1)+,r0
+	mov	r1,-8.(r1)
+	rts	r5
+
+/ write word to output buffer
+wrhdr:
+	mov	(r5)+,r1
+	mov	(r5)+,r2
+	mov	(r2),0f
+	mov	infd,r0
+	sys	seek; 0:.=.+2; 0
+
+	mov	(r2),r0
+	bis	$777,r0
+	inc	r0
+	add	$8.,r1
+	mov	r1,-(sp)
+	add	$512.,(sp)
+	mov	r0,-(r1)
+	mov	(sp),-(r1)
+	sub	(r2)+,r0
+	sub	r0,(sp)
+	mov	(sp),-(r1)
+	mov	(sp)+,0f
+	cmp	(r2),r0
+	bge	1f
+	mov	(r2),r0
+1:
+	mov	r0,0f+2
+	mov	(r2),-(r1)
+	jsr	r5,doread; 0:.=.+2; .=.+2
+	rts	r5
+
+doread:
+	mov	(r5)+,0f
+	mov	(r5)+,0f+2
+	mov	infd,r0
+	sys	read; 0:.=.+2; 0:.=.+2
+	bec	1f
+	cmp	r0,-4(r5)
+	bne	1f
+	rts	r5
+1:
+	jsr	r5,errout
+		rderr; .even
+	jmp	onerr
+
+/ relocation routines
+reloc:
+	mov	(r5)+,r1
+	sub	$2,(r1)+
+	bge	1f
+	sev
+	rts	r5
+1:
+	mov	(r1)+,r2
+	cmp	r2,(r1)+
+	bhis	2f
+	mov	(r2)+,r0
+	mov	r2,-4(r1)
+	rts	r5
+2:
+	mov	(r1),0f
+	mov	infd,r0
+	sys	seek; 0:.=.+2; 0
+	bic	$177000,r1
+	add	r2,r1
+	mov	r1,0f
+	mov	r2,r0
+	bis	$777,-(r2)
+	inc	(r2)
+	cmp	-(r2),-(r2)
+	sub	(r2),r1
+	neg	r1
+	mov	r1,0f+2
+	mov	r0,(r2)
+	mov	infd,r0
+	sys	write; 0:.=.+2; 0:.=.+2
+	rts	r5
+
+/ symbol table lookup
+lookup:
+	mov	$sysname,r1
+	mov	(r1)+,r0
+	add	(r1)+,r0
+	add	(r1)+,r0
+	add	(r1)+,r0
+	mov	r0,hession
+	clr	hession+2
+	mov	$1000.,hession+8.
+	mov	hession,r4
+	asl	r4
+	add	$hashbuf,r4
+	mov	(r4)+,r0
+	beq	notfound
+	mov	$sysname,r1
+	cmp	(r1)+,(r0)+
+	bne	1b
+	cmp	(r1)+,(r0)+
+	bne	1b
+	cmp	(r1)+,(r0)+
+	bne	1b
+	cmp	(r1)+,(r0)+
+	bne	1b
+notfound:
+	tst	-(r4)
+	rts	pc
+
+/ allocate new symbol
+newsym:
+	mov	symptr,r0
+	add	$12.,r0
+	cmp	r0,0f
+	blo	1f
+	add	$500.,r0
+	mov	r0,0f
+	sys	break; 0:symtab
+	mov	symptr,r0
+	mov	$sysname,r1
+	mov	$6,-(sp)
+1:
+	mov	(r1)+,(r0)+
+	dec	(sp)
+	bne	1b
+	mov	r0,symptr
+	tst	(sp)+
+	rts	pc
+
+/ error output
+errout:
+	jsr	pc,seterr
+	tst	outfd
+	beq	1f
+	mov	$1,r0
+	sys	write; errch; 1
+1:
+	mov	(sp)+,r1
+	mov	$8.,-(sp)
+1:
+	movb	(r1)+,errch
+	beq	2f
+	mov	$1,r0
+	sys	write; errch; 1
+	dec	(sp)
+	bne	1b
+2:
+	tst	(sp)+
+	mov	(sp)+,r1
+	br	errout2
+
+errmsg:
+	jsr	pc,seterr
+	mov	$1,r0
+	sys	write; errch; 1
+	rts	r5
+
+seterr:
+	mov	$17.,770.
+	mov	r1,-(sp)
+	mov	(r5)+,r1
+1:
+	movb	(r1)+,errch
+	beq	2f
+	mov	$1,r0
+	sys	write; errch; 1
+	br	1b
+2:
+	mov	outfd,r1
+	beq	3f
+1:
+	movb	(r1)+,errch
+	beq	3f
+	mov	$1,r0
+	sys	write; errch; 1
+	br	1b
+3:
+	mov	(sp)+,r1
+	rts	pc
+
+errout2:
+	br	errout+4
+
+/ put word
+putw:
+	mov	r1,-(sp)
+	mov	r2,-(sp)
+	mov	(r5)+,r2
+	mov	(r2)+,r1
+	cmp	r1,(r2)
+	bhis	1f
+	mov	r0,(r1)+
+	mov	r1,-(r2)
+	br	2f
+1:
+	tst	(r2)+
+	mov	r0,-(sp)
+	jsr	r5,doflush
+	mov	@(r2)+,-(sp)
+	add	$2,-(r2)
+2:
+	mov	(sp)+,r2
+	mov	(sp)+,r1
+	rts	r5
+
+doflush:
+	mov	(r5)+,r2
+	cmp	(r2)+,(r2)+
+	mov	(r2)+,r1
+	mov	r1,0f
+	mov	outfd,r0
+	sys	seek; 0:.=.+2; 0
+	bic	$177000,r1
+	add	r2,r1
+	mov	r1,0f
+	mov	r2,r0
+	bis	$777,-(r2)
+	inc	(r2)
+	cmp	-(r2),-(r2)
+	sub	(r2),r1
+	neg	r1
+	mov	r1,0f+2
+	mov	r0,(r2)
+	mov	outfd,r0
+	sys	write; 0:.=.+2; 0:.=.+2
+	rts	r5
+
+/ read symbol table
+rdsymtab:
+	mov	$6,-(sp)
+	mov	$sysname,r4
+1:
+	jsr	r5,reloc
+		outbf
+	bvs	2f
+	mov	r0,(r4)+
+	dec	(sp)
+	bne	1b
+	tst	(sp)+
+	rts	r5
+2:
+	tst	(sp)+
+	sev
+	rts	r5
+
+/ scan arguments
+argscan:
+	mov	bufptr,r0
+	add	$4,bufptr
+	mov	(r0)+,r0
+	beq	scandone
+	cmp	r0,$177
+	bhi	1f
+	cmp	r0,$1
+	beq	reloc1
+	movb	r0,libch
+	mov	$entry,r0
+1:
+	jsr	r5,doopen
+	br	argscan
+reloc1:
+	mov	(r1),nflag
+	beq	argscan
+	sub	$16.,(r1)
+	mov	(r1),0f
+	mov	infd,r0
+	sys	seek; 0:.=.+2; 0
+scandone:
+	mov	infd,r0
+	sys	read; hdrrd; 32.
+	mov	$hdrrd,r4
+	add	nflag,nflag
+	cmp	endflg,$'
+	beq	doentry
+	tst	(r4)+
+	mov	$18.,nflag
+argscan2:
+	add	argc,argc
+	beq	done2
+	mov	argv,r1
+	tst	(r1)+
+	mov	r1,argv
+	cmpb	@0(r1),$'-
+	bne	1f
+	jsr	r5,dosw
+	br	argscan2
+1:
+	clr	nflag
+	clr	argc
+	mov	@argv,r0
+	clr	entpt
+	jsr	r5,doopen
+	br	argscan2
+
+doentry:
+	mov	infd,r0
+	sys	read; hdrrd; 34.
+	bhis	1f
+	mov	r0,r3
+	mov	$hdrrd,r4
+	add	r4,r3
+	cmp	r3,$hdrbf
+	bhis	doformaterr
+	cmp	(r4),symhdr
+	bne	doentry2
+	cmp	r3,$hdrbf2
+	bhis	doformaterr
+	tst	(r4)+
+	mov	$18.,nflag
+
+doentry2:
+	cmp	(r4)+,magic
+	bne	doformaterr
+	mov	$txtbf,r1
+	mov	nflag,r2
+	add	$16.,r2
+	mov	(r4)+,r0
+	mov	r2,(r1)+
+	mov	r0,(r1)+
+	add	r0,r2
+	mov	(r4)+,r0
+	mov	r2,(r1)+
+	mov	r0,(r1)+
+	add	r0,r2
+	mov	(r4)+,(r1)+
+	mov	r2,(r1)+
+	mov	offset,(r1)
+	add	(r1)+,r2
+	mov	r2,(r1)+
+	mov	offset+2,(r1)
+	add	(r1)+,r2
+	mov	(r4)+,r0
+	mov	r2,(r1)+
+	mov	r0,(r1)+
+	mov	(r4)+,r0
+	cmp	r0,hitext
+	blo	1f
+	mov	r0,hitext
+1:
+	mov	(r4)+,ession
+	tst	(r4)+
+	beq	1f
+	jsr	r5,errout
+		err2; .even
+	rts	r5
+1:
+	tst	(r5)+
+	rts	r5
+
+doformaterr:
+	jsr	r5,errout
+		err1; .even
+	jmp	onerr
+
+/ handle switches
+dosw:
+	mov	(r1),r0
+	movb	1(r0),r0
+	cmpb	r0,$'u
+	beq	dosw_u
+	cmpb	r0,$'l
+	beq	dosw_l
+	cmpb	r0,$'x
+	beq	dosw_x
+	cmpb	r0,$'e
+	beq	dosw_e
+	cmpb	r0,$'r
+	beq	dosw_r
+	cmpb	r0,$'s
+	beq	dosw_s
+	rts	r5
+
+dosw_s:
+	inc	sflag
+	inc	nflag
+	rts	r5
+
+dosw_r:
+	clr	rflag
+	rts	r5
+
+dosw_x:
+	inc	nflag
+	rts	r5
+
+dosw_l:
+	movb	$'a,libch
+	mov	(r1),r1
+	movb	2(r1),r0
+	beq	1f
+	movb	r0,libch
+1:
+	mov	$entry, at argv
+	tst	(r5)+
+	rts	r5
+
+dosw_e:
+	clr	r4
+	jsr	r5,dosw_u
+	mov	(r4),ession
+	rts	r5
+
+dosw_u:
+	dec	argc
+	blt	done2
+	add	$2,argv
+	mov	@argv,r0
+	mov	$sysname,r1
+	mov	$8.,-(sp)
+1:
+	movb	(r0)+,(r1)+
+	beq	2f
+	dec	(sp)
+	bgt	1b
+2:
+	dec	(sp)
+	ble	3f
+	clrb	(r1)+
+	br	2b
+3:
+	tst	(sp)+
+	mov	$' ,(r1)+
+	clr	(r1)+
+	jsr	r5,lookup
+	tst	(r4)
+	bne	done2
+	jsr	r5,newsym
+done2:
+	rts	r5
+
+rdsymtab2:
+	mov	hession,r0
+	bic	$177700,r0
+	beq	1f
+	cmp	r0,$5
+	bhis	1f
+	asl	r0
+	add	@reltab(r0),hession+2
+1:
+	rts	r5
+
+findslot:
+	mov	$symlst,r4
+	cmp	r4,symend
+	bhis	1f
+	cmp	(r4)+,r2
+	beq	2f
+	tst	(r4)+
+	br	findslot+4
+1:
+	jsr	r5,errout
+		err7; .even
+	jmp	onerr
+2:
+	mov	(r4),r4
+	rts	r5
+
+/ open input file
+doopen:
+	clr	entpt
+	mov	r0,0f
+	mov	r0,outfd
+	mov	infd,r0
+	beq	1f
+	sys	close
+1:
+	sys	open; 0:.=.+2; 0
+	bec	1f
+	jsr	r5,errout
+		err6; .even
+	rts	r5
+1:
+	mov	r0,infd
+	tst	(r5)+
+	rts	r5
+
+/ do final relocation
+doreloc:
+	add	offset,tsize
+	add	offset+2,dsize
+	add	offset+4,bsize
+	rts	r5
+
+/ error messages
+outmsg:	<a.out\0>
+ldmsg:	<l.out\0>
+err1:	<: Can't move output file\n\0>
+	.even
+err2:	<No relocation bits: \0>
+	.even
+err3:	<Too many routines loaded at: \0>
+	.even
+err4:	<Multiply defined: \0>
+	.even
+err5:	<Too many symbols in: \0>
+	.even
+err6:	<Relocation error in: \0>
+	.even
+rderr:	<Premature EOF on: \0>
+	.even
+ldcan:	<ld: can't create l.out\n\0>
+	.even
+filerr:	<File not found: \0>
+	.even
+fmterr:	<Format error: \0>
+	.even
+err7:	<Symbol not found: \0>
+	.even
+err8:	<Multiple entry point:\n\0>
+	.even
+libpth:	</usr/lib\0>
+liba:	</lib\0>
+libd:	<a.a\0>
+	.even
+resvd:	0:.=.+2
+magic:	407
+
+.bss
+tsize:	.=.+2
+dsize:	.=.+2
+bsize:	.=.+2
+hitext:	.=.+2
+offset:	.=.+6
+argc:	.=.+2
+argv:	.=.+2
+outfd:	.=.+2
+infd:	.=.+2
+sflag:	.=.+2
+rflag:	.=.+2
+nflag:	.=.+2
+endflg:	.=.+2
+entpt:	.=.+2
+errcnt:	.=.+2
+ession: .=.+2
+outfn:	.=.+14.
+libch:	.=.+2
+outtxt:	.=.+2
+outdat:	.=.+2
+outbss:	.=.+2
+errch:	.=.+2
+pass2txt: .=.+2
+bufptr:	.=.+2
+symptr:	.=.+2
+symend:	.=.+2
+sysname: .=.+16.
+hdrrd:	.=.+34.
+hession: .=.+12.
+outbf:	.=.+512.
+txtbf:	.=.+512.
+datbf:	.=.+512.
+rdbf:	.=.+512.
+sdbf:	.=.+512.
+rtbf:	.=.+512.
+hdrbf:	.=.+34.
+hdrbf2:
+outhdr:	.=.+16.
+symhdr:	.=.+16.
+reltab:	.=.+10.
+hashbuf: .=.+2048.
+entry:	.=.+14.
+symlst:
+symtab = symlst+1000.
diff --git a/cmd/maki.s b/cmd/maki.s
new file mode 100644
index 0000000..1bd8907
--- /dev/null
+++ b/cmd/maki.s
@@ -0,0 +1,68 @@
+/ maki -- copy tape to disk (tape make)
+
+	br	start
+	bne	1f
+	0
+	0
+	0
+	0
+	0
+	0
+
+start:
+	sys	open; src; 0
+	bes	error
+	mov	r0,r1
+	sys	read; buf; 512.
+	mov	r1,r0
+	sys	close
+	sys	open; dst; 1
+	bes	error
+	mov	r0,r1
+	sys	write; buf; 512.
+	bes	error
+	sys	open; rf0; 0
+	bes	error
+	mov	r0,r2
+	jsr	pc,copy
+	mov	r1,r0
+	sys	close
+	sys	open; dst2; 1
+	bes	error
+	mov	r0,r1
+	jsr	pc,copy
+	sys	exit
+
+copy:
+	mov	$512.,-(sp)
+1:
+	mov	r2,r0
+	sys	read; buf; 512.
+	bes	error
+	mov	r1,r0
+	sys	write; buf; 512.
+	bes	error
+	dec	(sp)
+	bne	1b
+	tst	(sp)+
+	rts	pc
+
+error:
+	mov	$1,r0
+	sys	write; errmsg; 16.
+	sys	exit
+
+errmsg:	<error in copy\n\0>
+	.even
+
+src:	</dev/tap0\0>
+	.even
+dst:	</dev/tap1\0>
+	.even
+rf0:	</dev/rf0\0>
+	.even
+dst2:	</etc/std0\0>
+	.even
+
+.bss
+buf:	.=.+512.
diff --git a/cmd/mv.s b/cmd/mv.s
new file mode 100644
index 0000000..7bd81b3
--- /dev/null
+++ b/cmd/mv.s
@@ -0,0 +1,157 @@
+/ mv -- move/rename files
+
+	mov	(sp)+,r2
+	tst	(sp)+
+	cmp	r2,$2
+	blt	badcount
+	mov	(sp),r4
+	cmpb	(r4)+,$'-
+	bne	1f
+	cmpb	(r4),$'d
+	bne	1f
+	tst	(sp)+
+	dec	r2
+	incb	dflag
+1:
+	cmp	r2,$3
+	beq	2f
+badcount:
+	jsr	r5,error
+	<Arg count\n\0>
+	.even
+2:
+	mov	(sp)+,r3
+	mov	(sp)+,r4
+	mov	r3,0f
+	sys	stat; 0:..; sstbuf
+	bes	noexit
+	jsr	r5,error
+	<Source file non-existent\n\0>
+	.even
+noexit:
+	mov	sstbuf+8.,mq
+	mov	sstbuf+6.,ac
+	bit	$40000,sstbuf+4
+	bne	destdir
+	mov	r4,0f
+	sys	stat; 0:..; dstbuf
+	bes	samename
+	jsr	r5,error
+	<Directory mv target exists\n\0>
+	.even
+samename:
+	mov	r3,r0
+	mov	r4,r1
+1:
+	cmpb	(r0),(r1)
+	bne	2f
+	inc	r0
+	tstb	(r1)+
+	bne	1b
+	sys	exit
+2:
+	tstb	(r0)
+	beq	gotbase
+	cmpb	(r0)+,$'/
+	bne	2b
+	br	1b+4
+
+gotbase:
+	tstb	(r1)
+	beq	dolink
+	cmpb	(r1)+,$'/
+	bne	gotbase
+	jsr	r5,error
+	<Directory mv only to same level.\n\0>
+	.even
+dolink:
+	cmpb	-(r0),$'.
+	bne	trylink
+	jsr	r5,error
+	<Cannot link to . or ..\n\0>
+	.even
+trylink:
+	br	link
+
+destdir:
+	sys	setuid
+	sys	getuid
+	mov	r4,0f
+	sys	stat; 0:..; dstbuf
+	bes	link
+	bit	$40000,dstbuf+4
+	beq	checkid
+	mov	$nch,r1
+1:
+	movb	(r4)+,(r1)+
+	bne	1b
+	movb	$'/,-1(r1)
+	mov	r3,r4
+	mov	r3,r0
+1:
+	tstb	(r4)
+	beq	2f
+	cmpb	(r4)+,$'/
+	bne	1b
+	mov	r4,r0
+	br	1b
+2:
+	movb	(r0)+,(r1)+
+	bne	2b
+	mov	$nch,r4
+	br	destdir
+
+checkid:
+	cmp	sstbuf+2,dstbuf+2
+	bne	delold
+	jsr	r5,error
+	<Files are identical.\n\0>
+	.even
+delold:
+	mov	r4,0f
+	sys	unlink; 0:..
+	bec	link
+	jsr	r5,error
+	<Cannot remove target file.\n\0>
+	.even
+link:
+	mov	r3,0f
+	mov	r4,0f+2
+	sys	link; 0:..; 0:..
+	bec	unl
+	jsr	r5,error
+	<Cannot link target file.\n\0>
+	.even
+unl:
+	mov	r3,0f
+	sys	unlink; 0:..
+	bec	date
+	jsr	r5,error
+	<Cannot unlink source file.\n\0>
+	.even
+date:
+	tstb	dflag
+	beq	done
+	mov	r4,0f
+	sys	smdate; 0:..
+	bec	done
+	jsr	r5,error
+	<Can set modified date back.\n\0>
+	.even
+done:
+	sys	exit
+
+error:
+	movb	(r5)+,ch
+	beq	1f
+	mov	$1,r0
+	sys	write; ch; 1
+	br	error
+1:
+	sys	exit
+
+ch:	.=.+2
+dflag:	.=.+2
+sstbuf:	.=.+40.
+dstbuf:	.=.+40.
+nch:	.=.+128.
diff --git a/cmd/nm.s b/cmd/nm.s
new file mode 100644
index 0000000..07cc47d
--- /dev/null
+++ b/cmd/nm.s
@@ -0,0 +1,211 @@
+/ nm -- print symbol table
+
+	cmp	(sp)+,$2
+	blt	1f
+	tst	(sp)+
+	mov	(sp)+,0f
+1:
+	sys	open; 0:..; 0
+	bes	error
+	mov	r0,r1
+	sys	read; hdr; 16.
+	cmp	r0,$16.
+	bne	error
+	cmp	hdr,$432
+	beq	oldstyle
+	cmp	hdr,$407
+	bne	error
+	mov	hdr+6.,symsize
+	mov	hdr+2,0f
+	br	1f
+
+oldstyle:
+	mov	hdr+2,r2
+	add	hdr+6.,r2
+	cmp	hdr+14.,$1
+	beq	1f
+	asl	r2
+1:
+	add	$16.,r2
+	mov	r2,0f
+	mov	r1,r0
+	sys	seek; 0:..; 0
+	add	symsize,0f
+	sys	seek; 0f+2; 0
+	mov	r1,r0
+	sys	read; syms; 0:..
+	mov	$syms,r1
+	mov	r1,r2
+	add	r0,r2
+	mov	r2,-(sp)
+	mov	$12.,r3
+	jsr	pc,sort
+	mov	(sp)+,r4
+	mov	$syms,r1
+	br	loop
+error:
+	mov	$1,r0
+	sys	write; errmsg; 2
+	sys	exit
+
+loop:
+	cmp	r1,r4
+	bcc	done
+	mov	$line,r2
+	mov	8.(r1),r3
+	mov	r3,r5
+	bic	$177740,r3
+	bne	prval
+	mov	$6,r3
+1:
+	movb	$' ,(r2)+
+	dec	r3
+	bne	1b
+	br	prtype
+
+prval:
+	mov	10.(r1),num
+	clr	num-2
+	mov	$6,r3
+	mov	$1,lsh
+	br	1f
+2:
+	clr	num-2
+	mov	$3,lsh
+1:
+	add	$'0,num-2
+	movb	num-2,(r2)+
+	dec	r3
+	bne	2b
+
+prtype:
+	mov	r1,-(sp)
+	mov	r5,r3
+	bic	$40,r3
+	cmp	r3,$5
+	blo	1f
+	mov	$1,r3
+1:
+	movb	types(r3),(r2)+
+	movb	$' ,(r2)+
+	mov	$8.,r3
+	bit	$40,r5
+	beq	1f
+	movb	$'_,(r2)+
+	movb	$'\b,(r2)+
+1:
+	movb	(r1)+,(r2)+
+	beq	2f
+	dec	r3
+	bne	1b
+2:
+	movb	$'\n,(r2)+
+	sub	$line,r2
+	mov	r2,0f
+	mov	$1,r0
+	sys	write; line; 0:..
+	mov	(sp)+,r1
+	add	$12.,r1
+	br	loop
+
+done:
+	sys	exit
+
+0:	<a.out\0>
+	.even
+types:	<??UT B\0>
+	.even
+
+sort:
+	mov	r2,r0
+	sub	r1,r0
+	cmp	r0,r3
+	ble	sortdone
+	mov	r0,num
+	mov	r3,reclen
+	asr	num
+	mov	r3,num+2
+	mov	num,r4
+	add	r1,r4
+1:
+	mov	r1,-(sp)
+	mov	r2,-(sp)
+	mov	r1,r0
+	jsr	pc,compare
+	bge	2f
+	add	r3,r1
+	br	1b
+2:
+	cmp	r2,r4
+	blos	3f
+	sub	r3,r2
+	mov	r2,r0
+	jsr	pc,compare
+	bge	2b
+	jsr	pc,swap
+	cmp	r1,r4
+	bne	1b
+	mov	r2,r4
+	br	1b
+3:
+	cmp	r1,r4
+	beq	4f
+	jsr	pc,swap
+	mov	r1,r4
+	br	2b
+4:
+	mov	(sp)+,r2
+	mov	r4,-(sp)
+	mov	r4,r1
+	add	r3,r1
+	jsr	pc,sort
+	mov	(sp)+,r2
+	mov	(sp)+,r1
+	br	sort
+sortdone:
+	rts	pc
+
+compare:
+	mov	r3,-(sp)
+	mov	r4,-(sp)
+1:
+	cmpb	(r0)+,(r4)+
+	bne	2f
+	dec	r3
+	bne	1b
+	clr	r0
+	br	3f
+2:
+	blo	4f
+	mov	$1,r0
+	br	3f
+4:
+	mov	$-1,r0
+3:
+	mov	(sp)+,r4
+	mov	(sp)+,r3
+	tst	r0
+	rts	pc
+
+swap:
+	mov	r1,-(sp)
+	mov	r2,-(sp)
+	mov	r3,-(sp)
+1:
+	movb	(r1),r0
+	movb	(r2),(r1)+
+	movb	r0,(r2)+
+	dec	r3
+	bne	1b
+	mov	(sp)+,r3
+	mov	(sp)+,r2
+	mov	(sp)+,r1
+	rts	pc
+
+errmsg:	<?\n>
+hdr:	.=.+16.
+symsize: .=.+2
+num:	.=.+4
+reclen:	.=.+2
+line:	.=.+40.
+syms:
diff --git a/cmd/od.s b/cmd/od.s
new file mode 100644
index 0000000..fbeae73
--- /dev/null
+++ b/cmd/od.s
@@ -0,0 +1,112 @@
+/ od -- octal dump
+
+	sys	break; end
+	mov	(sp)+,r1
+	tst	(sp)+
+	cmp	r1,$2
+	blt	error
+	mov	(sp)+,0f
+	sys	open; 0:..; 0
+	bes	error
+	mov	r0,fin
+	cmp	r1,$2
+	ble	1f
+	mov	(sp)+,r0
+2:
+	movb	(r0)+,r1
+	beq	1f
+	asl	offset
+	asl	offset
+	asl	offset
+	bic	$177770,r1
+	bis	r1,offset
+	br	2b
+1:
+	bic	$7,offset
+	cmp	addr,offset
+	beq	loop
+	jsr	pc,getw
+	br	1b
+
+loop:
+	mov	addr,r0
+	jsr	pc,praddr
+	mov	$8.,r1
+	mov	$' ,r0
+	jsr	pc,putc
+1:
+	jsr	pc,getw
+	mov	r0,-(sp)
+	blt	2f
+	mov	$' ,r0
+	jsr	pc,putc
+	br	3f
+2:
+	mov	$'-,r0
+	jsr	pc,putc
+3:
+	mov	(sp)+,r0
+	jsr	pc,praddr
+	dec	r1
+	bne	1b
+	mov	$'\n,r0
+	jsr	pc,putc
+	br	loop
+
+error:
+	mov	$1,r0
+	sys	write; errmsg; 4
+	sys	exit
+
+errmsg:	<?\n\0\0>
+
+getw:
+	bne	1f
+	cmp	bufp,$buf+512.
+	bne	2f
+	mov	fin,r0
+	sys	read; buf; 512.
+	bes	error
+	tst	r0
+	beq	done
+	mov	$buf,bufp
+2:
+	mov	@bufp,r0
+	add	$2,bufp
+	rts	pc
+
+done:
+	mov	$1,r0
+	sys	write; nl; 1
+	sys	exit
+nl:	<\n>
+
+praddr:
+	mov	r0,mq
+	inc	lsh
+	mov	$5,-(sp)
+1:
+	clr	ac
+	mov	$3,lsh
+	mov	ac,r0
+	add	$'0,r0
+	jsr	pc,putc
+	dec	(sp)
+	bne	1b
+	tst	(sp)+
+	rts	pc
+
+putc:
+	mov	r0,ch
+	mov	$1,r0
+	sys	write; ch; 1
+	rts	pc
+
+ch:	.=.+2
+offset:	.=.+2
+addr:	buf+512.
+fin:	.=.+2
+
+buf:	.=.+512.
+bufp:	.=.+2
+end:
diff --git a/cmd/pr.s b/cmd/pr.s
new file mode 100644
index 0000000..15cc545
--- /dev/null
+++ b/cmd/pr.s
@@ -0,0 +1,342 @@
+/ pr -- print/paginate files
+
+	sys	break; end
+	mov	(sp)+,nfiles
+	tst	(sp)+
+	clr	r0
+	sys	fstat; stbuf
+	bit	$1,stbuf+4
+	beq	loop
+	sys	gtty; ttybuf
+	mov	ttybuf,r0
+	sub	stbuf+4,r0
+	add	$'0,r0
+	movb	r0,ttyno
+	sys	stty; ttybuf; 14
+	bes	1f
+	inc	ttyflg
+1:
+loop:
+	clr	fin
+	mov	fin,r0
+	beq	1f
+	sys	close
+	clr	fin
+1:
+	dec	nfiles
+	bgt	2f
+	jmp	done
+2:
+	mov	(sp)+,r0
+	mov	r0,filnam
+	cmpb	(r0)+,$'-
+	bne	dofile
+	cmpb	(r0),$'l
+	bne	3f
+	mov	$78.,linesz
+	br	loop
+3:
+	cmpb	(r0),$'r
+	bne	4f
+	mov	$66.,linesz
+	br	loop
+4:
+	cmpb	(r0),$'m
+	bne	5f
+	clr	cflag
+	br	loop
+5:
+	cmpb	(r0),$'c
+	bne	dofile
+	inc	cflag
+	br	loop
+
+dofile:
+	mov	filnam,r0
+	jsr	r5,fopen; buf
+	bes	loop
+	tst	cflag
+	beq	2f
+	sys	fstat
+	mov	mq,fmtime
+	mov	ac,fmtime+2
+	br	3f
+2:
+	mov	fin,r0
+	sys	fstat; stbuf
+	mov	stbuf+32.,fmtime
+	mov	stbuf+30.,fmtime+2
+3:
+	clr	pageno
+	clr	eof
+	clr	pushc
+
+page:
+	jsr	pc,header
+	br	loop
+
+error:
+	mov	$1,r0
+	sys	write; errmsg; 2
+	mov	$1,r0
+	mov	fmtime,mq
+	mov	fmtime+2,ac
+	jsr	pc,prdate
+	mov	$1,r0
+	sys	write; errmsg+2; 2
+	inc	pageno
+	mov	filnam,r1
+	mov	r1,0f
+	mov	$-1,r0
+1:
+	inc	r0
+	tstb	(r1)+
+	bne	1b
+	mov	r0,0f+2
+	mov	$1,r0
+	sys	write; 0:..; 0:..
+	mov	$1,r0
+	sys	write; sp2; 6
+	mov	pageno,mq
+	jsr	pc,prpage
+	mov	$1,r0
+	sys	write; nl; 4
+	mov	linesz,r1
+	sub	$11.,r1
+body:
+	jsr	pc,prbody
+1:
+	jsr	pc,getc
+	cmp	r0,$'\n
+	bne	1b
+	dec	r1
+	bne	1b
+	mov	$1,r0
+	sys	write; nl; 5
+	br	page
+
+done:
+	tst	ttyflg
+	beq	1f
+	sys	stty; ttybuf; 15
+1:
+	sys	exit
+
+prpage:
+	clr	ac
+	mov	$10.,div
+	mov	ac,-(sp)
+	tst	mq
+	beq	1f
+	jsr	pc,prpage
+1:
+	mov	(sp)+,r0
+	add	$'0,r0
+	mov	r0,ch
+	mov	$1,r0
+	sys	write; ch; 1
+	mov	ch,r0
+	rts	pc
+
+prbody:
+	mov	pushc,r0
+	beq	1f
+	clr	pushc
+	rts	pc
+1:
+	tst	eof
+	beq	2f
+	mov	$'\n,r0
+	rts	pc
+2:
+	jsr	r5,getc; buf
+	bec	3f
+	mov	pc,eof
+	br	prbody
+3:
+	rts	pc
+
+header:
+	jsr	pc,prbody
+	mov	r0,pushc
+	tst	eof
+	bne	1f
+	add	$2,(sp)
+1:
+	rts	pc
+
+nl:
+	<\n\n   >
+sp2:	< Page \0>
+	.even
+tty:	</dev/tty0\0>
+	.even
+
+linesz:	66.
+fmtime:	.=.+4
+nfiles:	.=.+2
+eof:	.=.+2
+pushc:	.=.+2
+ch:	.=.+2
+fin:	.=.+2
+stbuf:	.=.+40.
+filnam:	.=.+2
+cflag:	.=.+2
+ttyflg:	.=.+2
+ttybuf:	.=.+6
+ttyno = tty+8.
+pageno:	.=.+2
+
+prdate:
+	mov	r1,-(sp)
+	sub	$16.,sp
+	mov	r0,r1
+	mov	sp,r0
+	jsr	pc,fmtdate
+	mov	r0,0f
+	mov	r1,r0
+	sys	write; 0:..; 17.
+	add	$16.,sp
+	mov	(sp)+,r1
+	rts	pc
+
+fmtdate:
+	mov	r2,-(sp)
+	mov	r3,-(sp)
+	cmp	ac,yrdays
+	blo	1f
+	bhi	2f
+	cmp	mq,yrdays+2
+	blo	1f
+2:
+	mov	ac,-(sp)
+	sub	yrdays+2,mq
+	sbc	(sp)
+	sub	yrdays,(sp)
+	mov	(sp)+,ac
+	mov	$29.,daylen
+1:
+	mov	$-4,lsh
+	mov	$26300.,div
+	mov	mq,r3
+	mov	ac,mq
+	mov	$2,lsh
+	mov	$17.,div
+	add	$17.,r0
+	jsr	r5,digit; 10.
+	jsr	r5,digit; 6
+	movb	$':,-(r0)
+	jsr	r5,digit; 10.
+	jsr	r5,digit; 6
+	movb	$':,-(r0)
+	mov	r3,mq
+	mov	$24.,div
+	mov	mq,r3
+	mov	ac,mq
+	jsr	r5,digit; 10.
+	jsr	r5,digit; 10.
+	mov	r2,$montab
+1:
+	cmp	(r2),r3
+	bgt	2f
+	sub	(r2)+,r3
+	br	1b
+2:
+	movb	$' ,-(r0)
+	sub	$montab,r2
+	asl	r2
+	add	$months,r2
+	inc	r3
+	mov	r3,mq
+	jsr	r5,digit; 10.
+	tst	mq
+	beq	1f
+	add	$'0,mq
+	movb	mq,-(r0)
+	br	2f
+1:
+	movb	$' ,-(r0)
+2:
+	movb	$' ,-(r0)
+	movb	-(r2),-(r0)
+	movb	-(r2),-(r0)
+	movb	-(r2),-(r0)
+	mov	(sp)+,r3
+	mov	(sp)+,r2
+	rts	pc
+
+digit:
+	clr	ac
+	mov	(r5)+,div
+	add	$'0,ac
+	movb	ac,-(r0)
+	rts	r5
+
+yrdays:	57544.; 4480.
+daylen:	31.; 28.; 31.; 30.; 31.; 30.; 31.; 31.; 30.; 31.; 30.
+montab = .-2
+months:
+	<   \0Jan\0Feb\0Mar\0Apr\0May\0Jun\0Jul\0Aug\0Sep\0Oct\0Nov\0Dec\0>
+	.even
+
+fopen:
+	mov	r1,-(sp)
+	mov	(r5)+,r1
+	mov	r0,0f
+	sys	open; 0:..; 0
+	bec	1f
+	mov	$-1,(r1)
+	mov	(sp)+,r1
+	sec
+	rts	r5
+1:
+	mov	r0,(r1)+
+	clr	(r1)+
+	mov	(sp)+,r1
+	rts	r5
+
+getword:
+	mov	(r5),0f
+	mov	(r5)+,0f+2
+	jsr	r5,getc; 0:..
+	bec	1f
+	rts	r5
+1:
+	mov	r0,-(sp)
+	jsr	r5,getc; 0:..
+	swab	r0
+	bis	(sp)+,r0
+	rts	r5
+
+getc:
+	mov	r1,-(sp)
+	mov	(r5)+,r1
+	dec	2(r1)
+	bge	2f
+	mov	r1,r0
+	add	$6,r0
+	mov	r0,0f
+	mov	r0,4(r1)
+	mov	(r1),r0
+	sys	read; 0:..; 512.
+	bec	1f
+1:
+	tst	r0
+	bne	3f
+	mov	(sp)+,r1
+	sec
+	rts	r5
+3:
+	dec	r0
+	mov	r0,2(r1)
+2:
+	clr	r0
+	bisb	@4(r1),r0
+	inc	4(r1)
+	mov	(sp)+,r1
+	rts	r5
+
+errmsg:	<?\n>
+
+buf:	.=.+518.
+end:
diff --git a/cmd/roff.s b/cmd/roff.s
new file mode 100644
index 0000000..6b071f4
--- /dev/null
+++ b/cmd/roff.s
@@ -0,0 +1,1025 @@
+/ roff -- text formatter
+
+	cmp	sp,$57544
+	bhi	1f
+	jsr	r5,memerr
+		<Too many files.\n\0>; .even
+	sys	exit
+1:
+	clr	r0
+	jsr	pc,init
+	sys	exit
+	br	done
+
+/ stack check and initialization
+start:
+	clr	r0
+	jsr	pc,init
+	sys	creat; fname; 17
+	bes	error
+	mov	r0,outfd
+	tst	(sp)+
+	mov	(sp)+,0f
+1:
+	mov	$buf,r4
+	jsr	r5,descend
+	cmp	r4,$buf
+	beq	2f
+	jsr	pc,flush
+	br	1b
+2:
+	mov	$1,r0
+	sys	write; header+1; 3
+	mov	outfd,r0
+	beq	done
+	sys	close
+	sys	open; fname; 0
+	bec	1f
+	br	error
+1:
+	mov	r0,tmpfd
+	br	done
+
+error:
+	mov	$1,r0
+	sys	write; errmsg; 5
+	sys	exit
+
+done:
+	tst	outfd
+	beq	1f
+	sys	creat; 0:..; 17
+	bec	1f
+	br	error
+1:
+	sys	open; dfile; 0
+	bes	error
+	mov	r0,dfd
+
+/ main processing loop
+loop:
+	clr	nlines
+	jsr	pc,getchar
+	cmpb	r0,escchar
+	beq	command
+	movb	r0,savec
+	jsr	pc,text
+	br	loop
+
+/ command processor
+command:
+	jsr	pc,getchar
+	mov	r0,-(sp)
+	jsr	pc,getchar
+	swab	r0
+	bis	(sp),r0
+	mov	$cmdtab,r1
+1:
+	mov	(r1)+,(sp)
+	bic	$100000,(sp)
+	cmp	r0,(sp)
+	bne	2f
+	mov	(r1),(sp)
+	tst	-(r1)
+	bpl	3f
+	jsr	pc,skipl
+	cmp	bptr,$bufend
+	bgt	4f
+	mov	reqaddr, at bptr
+	add	$2,bptr
+	mov	(sp),reqaddr
+	br	4f
+3:
+	jmp	@(sp)+
+2:
+	cmp	(r1)+,$-1
+	bne	1b
+4:
+	tst	(sp)+
+	rts	pc
+
+/ command table
+cmdtab:
+	<ad>; adjcmd
+	<bp>; bpcmd
+	<br>; brcmd
+	<cc>; cccmd
+	<ce>; cecmd
+	<ds>; dscmd
+	<fi>; ficmd
+	<in>; incmd
+	<ix>; ixcmd
+	<li>; licmd
+	<ll>; llcmd
+	<ls>; lscmd
+	<na>; nacmd
+	<ne>; necmd
+	<nf>; nfcmd
+	<pa>; pacmd
+	<pl>; plcmd
+	<sk>; skcmd
+	<sp>; spcmd
+	<ss>; sscmd
+	<ta>; tacmd
+	<ti>; ticmd
+	<tr>; trcmd
+	<ul>; ulcmd
+	<un>; uncmd
+	<he>; hecmd
+	<hx>; hxcmd
+	<fo>; focmd
+	<eh>; ehcmd
+	<oh>; ohcmd
+	<ef>; efcmd
+	<of>; ofcmd
+	<m1>; m1cmd
+	<m2>; m2cmd
+	<m3>; m3cmd
+	<m4>; m4cmd
+	<hc>; hccmd
+	<hy>; hycmd
+	<n1>; n1cmd
+	<n2>; n2cmd
+	<nn>; nncmd
+	<ni>; nicmd
+	<jo>; jocmd
+	<ar>; arcmd
+	<ro>; rocmd
+	<nx>; nxcmd
+	<po>; pocmd
+	<de>; decmd
+	<ig>; igcmd
+	<tc>; tccmd
+	<mk>; mkcmd
+	-1; -1
+
+/ various command routines
+
+adjcmd:
+	jsr	pc,skipl
+	inc	adj
+	rts	pc
+
+bpcmd:
+	jsr	pc,skipl
+	jsr	r5,getnum
+		0
+	jsr	pc,eject
+	rts	pc
+
+brcmd:
+	jsr	pc,brk
+	rts	pc
+
+cccmd:
+	jsr	pc,getch
+	jsr	pc,getchar
+	cmp	r0,$'\n
+	beq	1f
+	movb	r0,escchar
+1:
+	rts	pc
+
+cecmd:
+	jsr	pc,skipl
+	jsr	r5,getnum
+		cenline
+	jsr	pc,eject
+	mov	r0,cenline
+	rts	pc
+
+ficmd:
+	jsr	pc,skipl
+	inc	fill
+	rts	pc
+
+incmd:
+	jsr	pc,skipl
+	jsr	pc,getch
+	jsr	pc,getchar
+	cmp	r0,$'\n
+	beq	1f
+	mov	inset,inset2
+	rts	pc
+1:
+	mov	r0,savec
+	jsr	r5,getnum
+		inset
+	dec	r0
+	jsr	pc,eject
+	inc	r0
+	mov	r0,inset
+	mov	r0,inset2
+	rts	pc
+
+nacmd:
+	jsr	pc,skipl
+	clr	adj
+	rts	pc
+
+nfcmd:
+	jsr	pc,skipl
+	clr	fill
+	rts	pc
+
+llcmd:
+	jsr	pc,skipl
+	jsr	pc,eject
+	jsr	pc,getch
+	tst	nlines
+	bne	1f
+	jsr	r5,getnum
+		linelen
+	jsr	pc,eject
+	mov	r0,linelen
+1:
+	rts	pc
+
+plcmd:
+	jsr	pc,skipl
+	jsr	r5,getnum
+		0
+	jsr	pc,eject
+	mov	r0,plen
+	mov	r0,plen2
+	rts	pc
+
+spcmd:
+	jsr	r5,getnum
+		0
+	mov	r0,spbef
+	jsr	pc,init2
+	rts	pc
+
+sscmd:
+	jsr	r5,getnum
+		0
+	mov	r0,spaft
+	rts	pc
+
+tacmd:
+	mov	$tabs,r1
+	jsr	r5,getnum
+		0
+1:
+	jsr	pc,eject
+	dec	r0
+	ble	2f
+	movb	r0,(r1)+
+	br	1b
+2:
+	clrb	(r1)+
+	rts	pc
+
+ticmd:
+	jsr	pc,skipl
+	jsr	r5,getnum
+		tind
+	jsr	pc,eject
+	mov	r0,plen2
+	rts	pc
+
+trcmd:
+	jsr	r5,getnum
+		0
+	jsr	pc,eject
+	mov	r0,trlim
+	rts	pc
+
+ulcmd:
+	tst	ulflag
+	bne	1f
+	clr	ulflag
+	br	2f
+1:
+	inc	ulflag
+2:
+	jsr	pc,init2
+	rts	pc
+
+/ header/footer commands
+
+hecmd:
+	jsr	r5,hfset
+		htitle
+	mov	htitle,htitle2
+	mov	htitle,htitle3
+	rts	pc
+
+hxcmd:
+	jsr	r5,hfset
+		htitle
+	rts	pc
+
+focmd:
+	jsr	r5,hfset
+		ftitle
+	rts	pc
+
+ehcmd:
+	jsr	r5,hfset
+		htitle
+	rts	pc
+
+ohcmd:
+	jsr	r5,hfset
+		htitle2
+	rts	pc
+
+efcmd:
+	jsr	r5,hfset
+		ftitle
+	rts	pc
+
+ofcmd:
+	jsr	r5,hfset
+		ftitle2
+	rts	pc
+
+m1cmd:
+	jsr	r5,getnum
+		0
+	mov	r0,m1
+	br	mend
+m2cmd:
+	jsr	r5,getnum
+		0
+	mov	r0,m2
+	br	mend
+m3cmd:
+	jsr	r5,getnum
+		0
+	mov	r0,m3
+	br	mend
+m4cmd:
+	jsr	r5,getnum
+		0
+	mov	r0,m4
+mend:
+	jsr	pc,init2
+	rts	pc
+
+/ margin and number commands
+
+pocmd:
+	jsr	pc,getch
+	jsr	pc,getchar
+	cmp	r0,$'\n
+	beq	1f
+	mov	r0,r1
+	jsr	pc,getchar
+	cmp	r0,$'\n
+	bne	2f
+	mov	$' ,r0
+2:
+	movb	r0,trtab(r1)
+	br	pocmd
+1:
+	rts	pc
+
+n1cmd:
+	jsr	pc,skipl
+	mov	$1,nummode
+	br	numset
+
+n2cmd:
+	jsr	pc,skipl
+	mov	$2,nummode
+numset:
+	clr	numcnt
+	jsr	r5,getnum
+		0
+1:
+	tst	r0
+	ble	2f
+	mov	r0,nummax
+	rts	pc
+2:
+	clr	nummode
+	rts	pc
+
+nncmd:
+	jsr	r5,getnum
+		0
+	mov	r0,numcnt
+	rts	pc
+
+nicmd:
+	jsr	r5,getnum
+		nind
+	jsr	pc,eject
+	mov	r0,nind
+	rts	pc
+
+/ text processing routines
+
+text:
+	clr	wrdflag
+	clr	nwords
+	clr	nchars
+	clr	hypflag
+	mov	$outbuf,wptr
+	clr	-(sp)
+	jsr	pc,gchar
+	cmp	r0,$'\n
+	beq	txtend
+	cmp	r0,hypchar
+	bne	1f
+	inc	hypflag
+	br	2b
+1:
+	cmp	$' ,r0
+	bne	3f
+	jsr	pc,putsp
+	br	2b
+3:
+	mov	r0,-(sp)
+	mov	$' ,r0
+	jsr	pc,putsp
+	tst	dotflag
+	beq	4f
+	jsr	pc,putsp
+	clr	dotflag
+4:
+	mov	(sp)+,r0
+	jsr	pc,putch
+	bisb	r0, at lastch
+	clr	(sp)
+	jsr	pc,gchar
+	cmp	r0,hypchar
+	bne	5f
+	inc	hypflag
+	jsr	pc,gchar
+	mov	$200,(sp)
+5:
+	cmp	$' ,r0
+	beq	6f
+	cmp	$'\n,r0
+	bne	4b
+	cmpb	-1(wptr),$'.
+	bne	6f
+	inc	dotflag
+6:
+	add	$2,2(sp)
+	clrb	(wptr)+
+txtend:
+	tst	(sp)+
+	mov	$outbuf,wptr
+	tst	nwords
+	bne	1f
+	jsr	pc,1f
+1:
+	rts	pc
+
+/ output routines
+
+putch:
+	cmp	wptr,$bufend
+	bcc	1f
+	movb	r0, at wptr
+	inc	wptr
+	jsr	pc,charwid
+	add	r1,cwid
+	sub	r1,remain
+	inc	nchars
+1:
+	rts	pc
+
+putsp:
+	mov	$outbuf,r2
+	clr	nspaces
+	clr	nwords
+1:
+	movb	(r2)+,r0
+	cmp	$' ,r0
+	bne	2f
+	jsr	pc,space
+	tst	nwords
+	bne	1b
+	br	3f
+2:
+	jsr	pc,emit
+	dec	nchars
+	bgt	1b
+3:
+	jsr	pc,newln
+	clr	nspaces
+	clr	cwid
+	mov	linelen,remain
+	mov	inset,wptr
+	rts	pc
+
+space:
+	inc	nspaces
+	tst	adj
+	beq	1f
+	inc	extrasp
+	cmp	extrasp,nspaces
+	blt	2f
+	inc	r0
+2:
+	jsr	pc,emit
+1:
+	rts	pc
+
+emit:
+	movb	r0, at optr
+	inc	optr
+	cmp	optr,$obufend
+	blo	1f
+	mov	outfd,r0
+	sys	write; obuf; 512.
+	mov	$obuf,optr
+1:
+	rts	pc
+
+newln:
+	mov	$'\n,r0
+	jsr	pc,emit
+	inc	lineno
+	rts	pc
+
+brk:
+	tst	splen
+	beq	1f
+	clrb	@optr
+	inc	pageno
+1:
+	jsr	pc,flush2
+	rts	pc
+
+eject:
+	tst	splen
+	beq	1f
+	sub	lineno,r0
+	neg	r0
+	jsr	pc,eject2
+	mov	r0,plen2
+	tst	nummode
+	beq	1f
+	add	$2,plen2
+1:
+	clr	extrasp
+	clr	wrdspc
+	mov	$1000,nspaces
+	mov	$' ,r0
+	jsr	pc,putch
+	jsr	pc,skipl
+	dec	trlim
+	bpl	2f
+	clr	trlim
+2:
+	rts	pc
+
+/ number output routines
+
+prnum:
+	mov	r0,mq
+1:
+	clr	ac
+	mov	$10.,div
+	mov	ac,-(sp)
+	tst	mq
+	beq	2f
+	jsr	pc,1b
+2:
+	mov	(sp)+,mq
+	add	$'0,mq
+	mov	outfd,r0
+	sys	write; mq; 1
+	rts	pc
+
+/ character width table
+charwid:
+	cmp	r0,hypchar
+	beq	2f
+	tst	r0
+	beq	2f
+	cmp	r0,$177
+	beq	2f
+	cmp	r0,$'\b
+	bne	1f
+	mov	$-1,r1
+	rts	pc
+1:
+	cmp	$' ,r0
+	bgt	2f
+	mov	$1,r1
+	rts	pc
+2:
+	clr	r1
+	rts	pc
+
+/ get character, handling escapes
+getchar:
+	mov	savec,r0
+	beq	1f
+	clr	savec
+	rts	pc
+1:
+	tst	nlines
+	bne	2f
+	mov	$'\n,r0
+	rts	pc
+2:
+	jsr	pc,getch
+	cmp	r0,$'\\
+	bne	3f
+	jsr	pc,getch
+	jsr	r5,escmap
+		esctab
+	br	4f
+3:
+	cmp	r0,$'\e
+	bne	4f
+	jsr	pc,getch
+	jsr	r5,escmap
+		esctab2
+4:
+	cmp	r0,$'\n
+	bne	5f
+	inc	nlines
+	clr	colno
+5:
+	mov	r1,-(sp)
+	jsr	pc,charwid
+	add	r1,colno
+	mov	(sp)+,r1
+	rts	pc
+
+/ escape character mapping
+escmap:
+	mov	r1,-(sp)
+	mov	(r5)+,r1
+1:
+	cmpb	(r1)+,r0
+	beq	2f
+	tstb	(r1)+
+	bne	1b
+	cmp	r1,$esctab2
+	ble	3f
+	cmp	r1,$esctab2e
+	bgt	3f
+	mov	$37,r0
+3:
+	mov	(sp)+,r1
+	rts	r5
+2:
+	movb	(r1)+,r0
+	mov	(sp)+,r1
+	rts	r5
+
+/ escape tables
+esctab:
+	<-\210\0n\012\0t\011\0\\\\134\0>\0\0>
+	.even
+esctab2:
+	<0\260\0-\304\0'\222\0`\223\0>\0\0>
+	.even
+esctab2e:
+
+/ getch from buffer or file
+getch:
+	tst	bcount
+	ble	1f
+	dec	bcount
+	mov	inptr,r0
+	rts	pc
+1:
+	mov	r1,-(sp)
+	tst	reqaddr
+	bne	2f
+	jsr	pc,readblk
+	br	3f
+2:
+	tst	fildes
+	bne	4f
+	mov	fptr,r1
+	cmp	r1,fend
+	bne	5f
+4:
+	mov	fname,r0
+	bne	6f
+	jsr	pc,open1
+6:
+	clr	fildes
+	sys	read; inbuf; 512.
+	bes	done
+	tst	r0
+	beq	done
+	mov	$inbuf,r1
+	add	r0,r1
+	mov	r1,fend
+5:
+	movb	(r1)+,r0
+	mov	r1,fptr
+	cmp	r0,$'\t
+	bne	3f
+	mov	(sp)+,r1
+	mov	$tabs,r0
+	inc	bcount
+	tstb	(r0)
+	beq	getch
+	cmpb	colno,(r0)+
+	bge	8f
+	movb	-(r0),bcount
+	sub	colno,bcount
+	br	getch
+8:
+	br	3f+2
+3:
+	br	7f
+7:
+	tst	r0
+	beq	2b
+	mov	(sp)+,r1
+	rts	pc
+
+/ open file for input
+open1:
+	mov	fname,r0
+	bne	1f
+	sys	close
+1:
+	tst	fildes
+	beq	2f
+	mov	$defout,1f
+	br	3f
+2:
+	dec	nfiles
+	blt	done
+	mov	@fnames,1f
+	add	$2,fnames
+3:
+	sys	open; 1:..; 0
+	bes	error
+	mov	r0,fname
+	rts	pc
+
+/ flush output buffer
+flush:
+	inc	nameloc
+	tst	outfd
+	beq	1f
+	movb	r0,(r4)+
+	cmp	r4,$buf+512.
+	blo	1f
+	mov	outfd,r0
+	sys	write; buf; 512.
+	mov	$buf,r4
+1:
+	rts	pc
+
+flush2:
+	mov	optr,r0
+	sub	$obuf,r0
+	mov	r0,0f
+	mov	$1,r0
+	sys	write; obuf; 0:..
+	mov	$obuf,optr
+	rts	pc
+
+/ initialization
+init:
+	mov	$obuf,optr
+	jsr	pc,init2
+	sys	exit
+
+init2:
+	mov	splen,r0
+	bne	1f
+	clr	plen2
+	rts	pc
+1:
+	sub	m3,r0
+	sub	m4,r0
+	sub	ulflag,r0
+	mov	r0,plen2
+	mov	linelen,r0
+	add	m1,r0
+	add	m2,r0
+	add	ulflag,r0
+	cmp	r0,plen2
+	blt	2f
+	mov	$2,r0
+	mov	r0,m1
+	mov	r0,m2
+	mov	r0,m3
+	mov	r0,m4
+	mov	$102.,splen
+	br	init2
+2:
+	cmp	lineno,plen2
+	ble	3f
+	mov	plen2,lineno
+3:
+	rts	pc
+
+/ get a number argument
+getnum:
+	jsr	pc,getch
+	mov	r1,-(sp)
+	clr	mq
+	clr	-(sp)
+	clr	-(sp)
+	jsr	pc,getchar
+	cmp	r0,$'+
+	beq	1f
+	cmp	r0,$'-
+	beq	1f
+	sub	$'0,r0
+	cmp	r0,$9.
+	bhi	2f
+	inc	(sp)
+	mov	$10.,mul
+	add	r0,mq
+	br	getnum+4
+1:
+	mov	r0,2(sp)
+	br	getnum+4
+2:
+	add	$'0,r0
+	mov	r0,savec
+	mov	(sp)+,r0
+	bne	3f
+	mov	$1,mq
+	mov	mq,r0
+3:
+	mov	(r5)+,r0
+	beq	4f
+	mov	(r0),r0
+4:
+	mov	(sp)+,r1
+	cmp	r1,$'-
+	bne	5f
+	sub	mq,r0
+	br	6f
+5:
+	cmp	r1,$'+
+	bne	7f
+	add	mq,r0
+	br	6f
+7:
+	mov	mq,r0
+6:
+	mov	(sp)+,r1
+	rts	r5
+
+/ header/footer setup
+hfset:
+	jsr	pc,getch
+	mov	r1,-(sp)
+	mov	(r5)+,r1
+	mov	r1,@(r5)+
+	jsr	pc,gchar
+	cmp	r0,$'\n
+	beq	3f
+	mov	r0,r2
+	jsr	pc,gchar
+	cmp	r0,$'\n
+	beq	3f
+	cmp	r0,r2
+	bne	2f
+	clr	r0
+2:
+	jsr	pc,wrchar
+	br	1b
+3:
+	clr	r0
+	jsr	pc,wrchar
+	mov	r1,hfptr
+	mov	linelen,hflen
+	rts	r5
+
+wrchar:
+	mov	r0,char
+	mov	1f,r0
+	mov	reqaddr,r1
+	sys	seek; 0:..; 0
+	mov	reqaddr,r0
+	sys	write; char; 1
+	inc	r1
+	cmp	reqaddr,reqmax
+	bne	1f
+	mov	$-1,reqmax
+1:
+	rts	pc
+
+/ skip to end of line
+skipl:
+	jsr	pc,getchar
+	cmp	r0,$'\n
+	bne	skipl
+	rts	pc
+
+/ hyphenation support
+hyphen:
+	tst	hypflag
+	bne	1f
+	tst	hyflag
+	beq	1f
+	inc	hypflag
+	mov	wptr,r0
+	clr	nwords
+1:
+	rts	pc
+
+/ data area
+defout:	</dev/tty0\0>
+	.even
+suftab:	</etc/suftab\0>
+	.even
+tmpfil:	</tmp/rtma\0>
+	.even
+
+reqmax:	-1; 4
+reqaddr: 0
+fptr:	0
+fend:	0
+fildes:	0
+fname:	0
+outfd:	0
+tmpfd:	0
+dfd:	0
+optr:	0
+wptr:	0
+bptr:	0
+bufend:	0
+obufend: 0
+inptr:	0
+bcount:	0
+nfiles:	0
+fnames:	0
+nameloc: 0
+
+/ formatting parameters
+escchar: '.
+hypchar: '-
+fill:	1
+adj:	0
+nlines:	0
+colno:	0
+savec:	0
+char:	0
+
+linelen: 65.
+inset:	0
+inset2:	0
+tind:	0
+plen:	66.
+plen2:	66.
+splen:	0
+spbef:	0
+spaft:	0
+trlim:	0
+cenline: 0
+ulflag:	0
+hypflag: 0
+dotflag: 0
+wrdflag: 0
+
+lineno:	0
+pageno:	0
+nspaces: 0
+extrasp: 0
+nchars:	0
+nwords:	0
+cwid:	0
+remain:	65.
+wrdspc:	0
+lastch:	0
+
+/ margin parameters
+m1:	2
+m2:	2
+m3:	2
+m4:	2
+
+/ numbering parameters
+nummode: 0
+numcnt:	0
+nummax:	0
+nind:	5
+
+/ title storage
+htitle:	0
+htitle2: 0
+htitle3: 0
+ftitle:	0
+ftitle2: 0
+hfptr:	0
+hflen:	0
+
+/ character translation table
+trtab:	.=.+256.
+
+/ tab settings
+tabs:	.=.+32.
+
+/ buffers
+obuf:	.=.+512.
+inbuf:	.=.+512.
+outbuf:	.=.+512.
+buf:	.=.+512.
+
+errmsg:	<err?\n>
diff --git a/cmd/size.s b/cmd/size.s
new file mode 100644
index 0000000..7e6897e
--- /dev/null
+++ b/cmd/size.s
@@ -0,0 +1,762 @@
+/ size -- print section sizes (B language program)
+
+	br	start
+	blt	regs
+	0
+	0
+	0
+	0
+	0
+	1
+
+/ threaded interpreter startup
+start:
+	mov	$mq,r3
+	mov	sp,r0
+	mov	(sp),-(sp)
+	tst	(r0)+
+	mov	r0,2(sp)
+	mov	60.,-(sp)
+	mov	$tbl,r5
+	jmp	@(r5)+
+
+/ tables and data
+tbl:
+	bic	(r5)+,r0
+	0
+lbl1:
+	bic	r0,@(sp)+
+	sys	exit
+lbl2:
+	bic	r0,-(r2)
+	bic	(r5)+, at -(r0)
+	18.
+	bic	(r5)+,-(r0)
+	26.
+	bic	(r3)+,-8.(r0)
+	bic	(r3)+, at -(r0)
+	4
+	bic	(r7),(sp)+
+	bic	(r3)+, at -(r0)
+	-24.
+	bic	(r4)+,r4
+	1
+	bic	(r7), at outbf(r0)
+	bic	r1,@(r0)+
+	bic	(r3)+, at -(r0)
+	6
+	bic	(r4)+,r4
+	bic	r6,(r2)
+	bic	(r7),(sp)+
+	bic	(r3)+,-24.(r0)
+	bic	(r2)+,(r4)+
+	bic	(r3)+,6(r0)
+	bic	(r2)+, at outbf(sp)
+	-24.
+	bic	(r2)+, at -(r0)
+	bic	(r5)+,outbf+4(sp)
+	bic	(r3)+,6(r0)
+	bic	(r2)+,-(r2)
+	bic	(r3)+,-22.(r0)
+	bic	(r4)+,r4
+	0
+	bic	(r3)+, at -(r0)
+	6
+	bic	(r1)+,outbf(r4)
+	bic	(r5),-(r4)
+	bic	(r4)+, at -(r0)
+	4
+	bic	(r7),@(r2)+
+	bic	(r4)+,r4
+	0
+	bic	(r0)+,(r0)+
+	bic	(r5)+,outbf+2(sp)
+	bic	(r3)+, at -(r0)
+	6
+	bic	(r1)+,outbf+4(r4)
+	bic	(r4)+,r4
+	bic	r6,(r0)+
+	bic	(r4)+,r0
+	bic	(r0),(r2)+
+	bic	(r5)+,r0
+	4
+	bic	(r4)+,r0
+	bic	r6,@(sp)+
+	bic	(r5)+,@(r4)+
+	bic	(r4)+,r4
+	16.
+	bic	(r3)+, at -(r0)
+	-20.
+	bic	(r3)+, at -(r0)
+	-22.
+	bic	(r4)+,r0
+	bic	(sp),4(r4)
+	bic	(r5)+,r0
+	6
+	bic	(r3)+, at -(r0)
+	-20.
+	bic	(r4)+,r4
+	0
+	bic	(r4)+,(sp)
+	bic	(r4)+,r4
+	br	1f
+
+1:
+	bic	(r0)+,r0
+	bic	(r5)+,outbf+6(sp)
+	bic	(r3)+, at -(r0)
+	6
+	bic	(r1)+,outbf+4(r4)
+	bic	(r4)+,r4
+	bic	r6,-(r0)
+	bic	(r4)+,r0
+	bic	(r0),(r2)+
+	bic	(r5)+,r0
+	4
+	bic	(r3)+, at -(r0)
+	-22.
+	bic	(r4)+,r0
+	bic	(r5),(r2)+
+	bic	(r5)+,r0
+	2
+	bic	(r4)+,r0
+	bic	r6,@(sp)+
+	bic	(r5)+,@(r4)+
+	bic	(r3)+, at -(r0)
+	4
+	bic	(r4)+,r4
+	2
+	bic	(r0)+,-(r0)
+	bic	(r5)+,outbf+16.(sp)
+	bic	(r3)+, at -(r0)
+	6
+	bic	(r1)+,outbf+4(r4)
+	bic	(r4)+,r4
+	bic	r6,outbf(r0)
+	bic	(r4)+,r0
+	bic	(r0),(r2)+
+	bic	(r5)+,r0
+	4
+	bic	(r3)+, at -(r0)
+	-20.
+	bic	(r4)+,r4
+	3
+	bic	(r4)+,(sp)
+	bic	(r3)+, at -(r0)
+	-20.
+	bic	(r4)+,r4
+	2
+	bic	(r4)+,(sp)
+	bic	(r3)+, at -(r0)
+	-20.
+	bic	(r4)+,r4
+	1
+	bic	(r4)+,(sp)
+	bic	(r4)+,r4
+	bic	r6,outbf(sp)
+	bic	(r4)+,r0
+	bic	(r0),(r2)+
+	bic	(r5)+,r0
+	8.
+	bic	(r3)+,-26.(r0)
+	bic	(r3)+, at -(r0)
+	-20.
+	bic	(r4)+,r4
+	1
+	bic	(r4)+,(sp)
+	bic	(r3)+, at -(r0)
+	-20.
+	bic	(r4)+,r4
+	2
+	bic	(r4)+,(sp)
+	bic	(r1)+,r6
+	bic	(r3)+, at -(r0)
+	-20.
+	bic	(r4)+,r4
+	3
+	bic	(r4)+,(sp)
+	bic	(r1)+,r6
+	bic	(r7),(sp)+
+	bic	(r3)+,-26.(r0)
+	bic	(r4)+,r4
+	bic	r7,r4
+	bic	(r4)+,r0
+	bic	(r0),(r2)+
+	bic	(r5)+,r0
+	4
+	bic	(r3)+, at -(r0)
+	-22.
+	bic	(r4)+,r0
+	bic	(r5),(r0)+
+	bic	(r5)+,r0
+	2
+	bic	(r4)+,r0
+	bic	(r5),(r0)+
+	bic	(r5)+,@(r4)+
+	bic	(r3)+,-4(r0)
+	bic	(r3)+, at -(r0)
+	-8.(r0)
+	bic	(r7),(sp)+
+	bic	(r3)+,-10.(r0)
+	bic	(r3)+,-4(r0)
+	bic	(r3)+,r4
+	bic	(r1)+, at hession(r0)
+	bic	(sp)+,r0
+	bic	(r4),@(r0)+
+	bic	(r3)+, at -(r0)
+	-8.(r0)
+	bic	(r4)+,r4
+	0
+	bic	(r0)+,(r0)+
+	bic	(r5)+,hession+4(sp)
+	bic	(r3)+, at -(r0)
+	-8.(r0)
+	bic	(r3)+, at -(r0)
+	-8.(r0)
+	bic	(r1)+,pD(r0)
+	bic	(r7),(sp)+
+	bic	(r4)+,r4
+	'-
+	bic	(r4)+,r0
+	bic	(sp),r2
+	bic	(r5)+,r0
+	2
+	bic	(r3)+, at -(r0)
+	-10.(r0)
+	bic	(r4)+,r4
+	'o
+	bic	(r7), at outbf(r0)
+	bic	(r2), at hession+2(r2)
+	bic	(r4)+,r4
+	8.
+	bic	(r5)+,hession+6(r2)
+	bic	(r4)+,r4
+	10.
+	bic	(r3)+, at -(r0)
+	-8.(r0)
+	bic	(r4)+,r0
+	bic	r7,(r2)
+	bic	(r5)+,r0
+	4
+	bic	(r4)+,r0
+	bic	(r5),(r0)+
+	bic	(r5)+,@(r4)+
+	bic	(r3)+, at -(r0)
+	-8.(r0)
+	bic	(r4)+,r0
+	bic	(sp),r2
+	bic	(r5)+,r0
+	2
+	bic	(r4)+,r0
+	bic	(r5),(r0)+
+	bic	(r5)+,@(r4)+
+	bic	(r3)+,-4(r0)
+	bic	(r3)+, at -(r0)
+	-8.(r0)
+	bic	(r7),(sp)+
+	bic	(r3)+,-10.(r0)
+	bic	(r3)+,-4(r0)
+	bic	(r3)+,r4
+	bic	(r1)+, at hession(r0)
+	bic	(r5)+,hession+16.(sp)
+	bic	(r3)+, at -(r0)
+	-10.(r0)
+	bic	(r4)+,r0
+	bic	(sp),r2
+	bic	(r5)+,r0
+	2
+	bic	(r5)+,hession+12.(r2)
+	bic	(r4)+,r0
+	bic	(r5),(r0)+
+	bic	(r5)+,@(r4)+
+	bic	(r5)+,outbf+2(r2)
+
+	jmp	-(r4)
+	bic	(r1),@'o(sp)
+	bic	(r1),@'c(sp)
+	bic	(r3),(r0)+
+	jmp	outbf+2(r3)
+	0
+	0
+	bic	(r4)+,r4
+	'%
+	bic	(r4)+,r0
+	bic	(sp),r2
+	bic	(r5)+,r0
+	2
+	bic	(r3)+,4(r0)
+	bic	(r2)+,outbf(r0)
+	-6.(r2)
+	bic	(r2)+, at outbf(sp)
+	bic	(r4)+,r0
+	bic	(r5),(r0)+
+	bic	(r5)+,@(r4)+
+	bic	(r5)+,-(r0)
+	2
+	bic	(r5)+,@(r0)+
+
+/ error strings
+aoutmsg:	<a.out\0>
+	.even
+notfnd:	<%s not found\n\0>
+	.even
+badfmt:	<Bad format: %s\n\0>
+	.even
+sfmt:	<%s: \0>
+	.even
+ofmt:	<%0o+%0o+%0o=\0>
+	.even
+ofmt2:	<%0o\n\0>
+	.even
+
+/ threaded interpreter primitives
+tstart:
+	bic	r7,(r4)
+	bic	(r5)+,-(r0)
+	4
+	bic	(r3)+,-4(r0)
+	bic	(r3)+, at -(r0)
+	4
+	bic	(r3)+, at -(r0)
+	6
+	bic	(r1)+,-(r4)
+	bic	(r7),@(r2)+
+	bic	(r5)+,outbf+14.(sp)
+	bic	(r3)+, at -(r0)
+	6
+	bic	(r3)+, at -(r0)
+	-4(r0)
+	bic	(r4)+,r0
+	bic	r7,(r2)
+	bic	(r5)+,r0
+	4
+	bic	(r3)+, at -(r0)
+	4
+	bic	(r3)+, at -(r0)
+	6
+	bic	(r1)+,(sp)
+	bic	(r4)+,r4
+	'0
+	bic	(r1)+,r6
+	bic	(r4)+,r0
+	bic	(sp),r2
+	bic	(r5)+,r0
+	2
+	bic	(r5)+,-(r0)
+	2
+	bic	(r5)+,@(r0)+
+	bic	(r5)+,-(r0)
+	10.
+	bic	(r3)+,-6.(r0)
+	bic	(r3)+,6(r0)
+	bic	(r7),(sp)+
+	bic	(r5)+,-(r0)
+	10.
+	bic	(r3)+,-10.(r0)
+	bic	(r3)+,4(r0)
+	bic	(r3)+,r4
+	bic	(r1)+, at hession(r0)
+	bic	(sp)+,hession+16.(sp)
+	bic	(r3)+, at -(r0)
+	-10.(r0)
+	bic	(r4)+,r0
+	bic	(sp),r2
+	bic	(r5)+,r0
+	2
+	bic	(r5)+,outbf+2(r2)
+	bic	(r5)+,-(r0)
+	2
+	bic	(r5)+,@(r0)+
+	bic	(r5)+,-(r2)
+
+/ sys call wrappers
+sdiv:
+	mov	4(r4),r0
+	clr	r1
+	sys	0; 6		/ div
+	adc	r1
+	mov	r1,r0
+	rts	pc
+
+sopen:
+	bic	(r5),-(sp)
+	bic	(r5), at -(r0)
+	mov	4(r4),0f
+	mov	6(r4),0f+2
+	sys	open; 0:.=.+2; 0:.=.+2
+	bec	1f
+	mov	$-1,r0
+1:
+	rts	pc
+
+sclose:
+	bic	(sp),r4
+	bic	(sp),sp
+	mov	4(r4),0f
+	mov	0f+2,r0
+	tstb	0f+1
+	beq	1f
+	sys	write; 0:.=.+2; 2
+	br	2f
+1:
+	sys	write; 0:.=.+2; 1
+2:
+	mov	0f,r0
+	rts	pc
+
+funct1:
+	bic	(sp), at -(r4)
+	bic	(sp), at -(sp)
+	rts	pc
+
+funct2:
+	0
+	1
+
+sread:
+	bic	(sp),-(sp)
+	bic	(sp),-(r0)
+	mov	4(r4),r0
+	mov	6(r4),0f
+	mov	8.(r4),0f+2
+	sys	read; 0:.=.+2; 0:.=.+2
+	bec	1f
+	mov	$-1,r0
+1:
+	rts	pc
+
+/ interpreter dispatch
+disp:
+	mov	@(sp)+,@(sp)+
+	jmp	@(r5)+
+
+disp2:
+	mov	(sp)+,r0
+	mov	r0,@(sp)+
+	mov	r0,-(sp)
+	jmp	@(r5)+
+
+disp3:
+	movb	(sp)+,@(sp)+
+	jmp	@(r5)+
+
+disp4:
+	mov	(sp)+,r0
+	movb	r0,@(sp)+
+	mov	r0,-(sp)
+	jmp	@(r5)+
+
+disp5:
+	bis	(sp)+,(sp)
+	jmp	@(r5)+
+
+disp6:
+	com	(sp)
+	bic	(sp)+,(sp)
+	jmp	@(r5)+
+
+/ comparison primitives
+cmpne:
+	cmp	(sp)+,(sp)+
+	beq	1f
+	clr	-(sp)
+	jmp	@(r5)+
+
+cmpeq:
+	cmp	(sp)+,(sp)+
+	bne	1f
+	clr	-(sp)
+	jmp	@(r5)+
+
+cmpge:
+	cmp	(sp)+,(sp)+
+	bge	1f
+	clr	-(sp)
+	jmp	@(r5)+
+
+cmpgt:
+	cmp	(sp)+,(sp)+
+	bgt	1f
+	clr	-(sp)
+	jmp	@(r5)+
+
+cmple:
+	cmp	(sp)+,(sp)+
+	ble	1f
+	clr	-(sp)
+	jmp	@(r5)+
+
+cmplt:
+	cmp	(sp)+,(sp)+
+	blt	1f
+	clr	-(sp)
+	jmp	@(r5)+
+
+1:
+	mov	$1,-(sp)
+	jmp	@(r5)+
+
+/ memory operations
+memop1:
+	mov	2(sp),-(r3)
+	sub	(sp)+,hession+4
+	mov	(r3)+,(sp)
+	jmp	@(r5)+
+
+memop2:
+	mov	2(sp),(r3)
+	mov	(sp)+,hession+4
+	mov	(r3),(sp)
+	jmp	@(r5)+
+
+/ arithmetic
+add:
+	add	(sp)+,(sp)
+	jmp	@(r5)+
+
+sub:
+	sub	(sp)+,(sp)
+	jmp	@(r5)+
+
+mul:
+	mov	2(sp),(r3)
+	mov	(sp)+,hession
+	mov	hession+2,(sp)
+	jmp	@(r5)+
+
+swap:
+	mov	(sp)+,(r3)+
+	mov	(sp)+,(r3)
+	mov	-(r3),-(sp)
+	jmp	@(r5)+
+
+div:
+	mov	2(sp),(r3)
+	mov	(sp)+,hession
+	mov	(r3),(sp)
+	jmp	@(r5)+
+
+neg:
+	neg	(sp)
+	jmp	@(r5)+
+
+/ indirection
+indir:
+	mov	@(sp)+,-(sp)
+	jmp	@(r5)+
+
+indirb:
+	movb	@(sp)+,r0
+	mov	r0,-(sp)
+	jmp	@(r5)+
+
+/ logical not
+not:
+	tst	(sp)+
+	bne	1f
+	mov	$1,-(sp)
+	jmp	@(r5)+
+1:
+	clr	-(sp)
+	jmp	@(r5)+
+
+/ increment/decrement
+preinc:
+	inc	@0(sp)
+	mov	@(sp)+,-(sp)
+	jmp	@(r5)+
+
+postinc:
+	inc	@(sp)+
+	jmp	@(r5)+
+
+preinc2:
+	add	$2, at 0(sp)
+	mov	@(sp)+,-(sp)
+	jmp	@(r5)+
+
+postinc2:
+	add	$2,@(sp)+
+	jmp	@(r5)+
+
+predec:
+	dec	@0(sp)
+	mov	@(sp)+,-(sp)
+	jmp	@(r5)+
+
+postdec:
+	dec	@(sp)+
+	jmp	@(r5)+
+
+predec2:
+	sub	$2, at 0(sp)
+	mov	@(sp)+,-(sp)
+	jmp	@(r5)+
+
+postdec2:
+	sub	$2,@(sp)+
+	jmp	@(r5)+
+
+/ post operations
+postop1:
+	mov	(sp)+,r0
+	mov	(r0),-(sp)
+	inc	(r0)
+	jmp	@(r5)+
+
+postop2:
+	mov	(sp)+,r0
+	mov	(r0),-(sp)
+	add	$2,(r0)
+	jmp	@(r5)+
+
+postop3:
+	mov	(sp)+,r0
+	mov	(r0),-(sp)
+	dec	(r0)
+	jmp	@(r5)+
+
+postop4:
+	mov	(sp)+,r0
+	mov	(r0),-(sp)
+	sub	$2,(r0)
+	jmp	@(r5)+
+
+/ frame operations
+frame1:
+	mov	(r5)+,r0
+	add	r4,r0
+	mov	(r0),-(sp)
+	jmp	@(r5)+
+
+frame2:
+	mov	(r5)+,-(sp)
+	add	r4,(sp)
+	jmp	@(r5)+
+
+frame3:
+	mov	(r5)+,r0
+	add	r4,r0
+	movb	(r0),r0
+	mov	r0,-(sp)
+	jmp	@(r5)+
+
+/ constants
+const1:
+	mov	@(r5)+,-(sp)
+	jmp	@(r5)+
+
+const2:
+	mov	(r5)+,-(sp)
+	jmp	@(r5)+
+
+const3:
+	movb	@(r5)+,r0
+	mov	r0,-(sp)
+	jmp	@(r5)+
+
+/ array operations
+arr1:
+	asl	(sp)
+	add	(sp)+,(sp)
+	mov	@(sp)+,-(sp)
+	jmp	@(r5)+
+
+arr2:
+	add	(sp)+,(sp)
+	movb	@(sp)+,r0
+	mov	r0,-(sp)
+	jmp	@(r5)+
+
+arr3:
+	asl	(sp)
+	add	(sp)+,(sp)
+	jmp	@(r5)+
+
+shiftl:
+	asl	(sp)
+	jmp	@(r5)+
+
+/ function call
+fcall:
+	mov	(sp)+,r0
+	mov	r5,-(sp)
+	mov	r4,-(sp)
+	mov	sp,r4
+	mov	r0,r5
+	jsr	pc,@(r5)+
+	mov	r4,sp
+	mov	(sp)+,r4
+	mov	(sp)+,r5
+	add	(r5)+,sp
+	mov	r0,-(sp)
+	jmp	@(r5)+
+
+fcall2:
+	mov	(sp)+,r0
+	mov	r5,-(sp)
+	mov	r4,-(sp)
+	mov	sp,r4
+	mov	r0,r5
+	jsr	pc,@(r5)+
+	mov	r4,sp
+	mov	(sp)+,r4
+	mov	(sp)+,r5
+	add	(r5)+,sp
+	jmp	@(r5)+
+
+/ control flow
+jind:
+	mov	(sp),r0
+	jmp	@-2(r4)
+
+ret:
+	mov	(sp)+,r5
+	jmp	@(r5)+
+
+setsp:
+	mov	r4,r0
+	sub	(r5)+,r0
+	mov	r0,sp
+	jmp	@(r5)+
+
+setsp2:
+	mov	r4,r0
+	sub	(r5)+,r0
+	mov	r0,sp
+	mov	r0,-(sp)
+	jmp	@(r5)+
+
+jmp1:
+	mov	(r5)+,r5
+	jmp	@(r5)+
+
+beq1:
+	mov	(r5)+,r0
+	tst	(sp)+
+	bne	1f
+	mov	r0,r5
+1:
+	jmp	@(r5)+
+
+switch:
+	mov	(r5)+,r5
+	mov	(sp)+,r0
+	cmp	r0,(r5)+
+	beq	2f
+	tst	(r5)+
+	bne	switch+4
+	jmp	@(r5)+
+2:
+	mov	(r5)+,r0
+	beq	1f
+	mov	r0,r5
+1:
+	jmp	@(r5)+
+
+/ data
+.bss
+regs:	.=.+12.
+hession: .=.+12.
+outbf:	.=.+520.
+mq = 177304
diff --git a/cmd/sort.s b/cmd/sort.s
new file mode 100644
index 0000000..39473b6
--- /dev/null
+++ b/cmd/sort.s
@@ -0,0 +1,265 @@
+/ sort -- sort lines
+
+	cmp	(sp)+,$3
+	beq	1f
+	sys	exit
+1:
+	tst	(sp)+
+	mov	(sp)+,0f
+	sys	open; 0:..; 0
+	bec	1f
+	sys	exit
+1:
+	mov	r0,fin
+	mov	(sp)+,r0
+	jsr	r5,fcreat; obuf
+	bec	1f
+	sys	exit
+1:
+	jsr	pc,sort
+	jsr	pc,output
+	sys	exit
+
+output:
+	mov	r1,-(sp)
+	cmp	r1,r2
+	bhi	1f
+	mov	(r1)+,r5
+	jsr	pc,getc1
+	mov	r0,-(sp)
+	jsr	r5,putc; obuf
+	mov	(sp)+,r0
+	cmp	r0,$'\n
+	beq	output
+	cmp	r0,$4
+	beq	output
+	br	2b
+1:
+	jsr	r5,flush; obuf
+	mov	(sp)+,r1
+	rts	pc
+
+getc1:
+	mov	r5,r0
+	bic	$777,r0
+	cmp	r0,blkno
+	beq	1f
+	mov	r0,blkno
+	mov	fin,r0
+	sys	seek; -1; 0
+	mov	fin,r0
+	sys	read; inbuf; 512.
+	mov	r0,nleft
+1:
+	mov	r5,r0
+	bic	$177000,r0
+	inc	r5
+	cmp	r0,nleft
+	blt	1f
+	mov	$4,r0
+	rts	pc
+1:
+	movb	inbuf(r0),r0
+	rts	pc
+
+compare:
+	mov	r5,-(sp)
+	mov	r4,-(sp)
+	mov	r0,-(sp)
+	mov	$line,r4
+	cmpb	(r4),$'(
+	bne	1f
+	inc	r4
+1:
+	cmpb	3720.(r5),$'(
+	beq	2f
+	cmpb	3720.(r5),(r4)+
+	blt	less
+	bgt	more
+2:
+	cmpb	3721.(r5),(r4)+
+	blt	less
+	bgt	more
+	mov	(r5),r5
+	add	$2,r5
+	jsr	pc,getc1
+	cmpb	r0,$'A
+	blo	3f
+	cmpb	r0,$'Z
+	bhi	3f
+	add	$40,r0
+3:
+	cmpb	r0,(r4)+
+	beq	1b
+	blt	less
+more:
+	mov	(sp)+,r0
+	mov	(sp)+,r4
+	mov	(sp)+,r5
+	tst	$-1
+	rts	pc
+
+less:
+	mov	(sp)+,r0
+	mov	(sp)+,r4
+	mov	(sp)+,r5
+	tst	$1
+	rts	pc
+
+sort:
+	mov	$lines,r1
+	mov	r1,r2
+	jsr	r5,getline
+	rts	pc
+
+insert:
+	mov	lineptr,(r1)
+	mov	lineptr+2,3720.(r1)
+	jsr	r5,getline
+	rts	pc
+
+bsearch:
+	mov	r1,r3
+	mov	r2,r4
+1:
+	mov	r3,r5
+	add	r4,r5
+	ror	r5
+	bic	$1,r5
+	jsr	pc,compare
+	beq	found
+	blt	2f
+	cmp	r5,r4
+	bcc	found
+	tst	(r5)+
+	mov	r5,r3
+	br	1b
+2:
+	cmp	r3,r4
+	bcc	found
+	mov	r5,r4
+	br	1b
+found:
+	tst	(r5)+
+	tst	(r2)+
+	cmp	r2,r5
+	beq	2f
+	mov	r2,r3
+1:
+	mov	-(r3),2(r3)
+	mov	3720.(r3),3722.(r3)
+	cmp	r3,r5
+	bhi	1b
+2:
+	mov	lineptr,(r5)
+	mov	lineptr+2,3720.(r5)
+	br	bsearch-4
+
+getline:
+	mov	r5,-(sp)
+	cmp	r2,$lines+2000.
+	bcc	1f
+	mov	loc,r5
+	mov	$line,r3
+	mov	r5,lineptr
+	jsr	pc,getc1
+	cmp	r0,$4
+	bne	2f
+1:
+	mov	(sp)+,r5
+	rts	r5
+2:
+	cmp	r0,$'\n
+	beq	3f
+	cmp	r3,$line+199.
+	bcc	1b
+	cmpb	r0,$'A
+	blo	4f
+	cmpb	r0,$'Z
+	bhi	4f
+	add	$40,r0
+4:
+	movb	r0,(r3)+
+	br	1b
+3:
+	clrb	(r3)+
+	mov	r5,loc
+	mov	(sp)+,r5
+	tst	(r5)+
+	rts	r5
+
+fcreat:
+	mov	r1,-(sp)
+	mov	(r5)+,r1
+	mov	r0,0f
+	sys	creat; 0:..; 17
+	bec	1f
+	mov	r0,(r1)+
+	clr	(r1)+
+	clr	(r1)+
+	mov	(sp)+,r1
+	rts	r5
+1:
+	mov	$-1,(r1)+
+	br	3b
+
+getword:
+	mov	(r5),0f
+	mov	(r5)+,0f+2
+	mov	r0,-(sp)
+	jsr	r5,getc; 0:..
+	mov	(sp)+,r0
+	swab	r0
+	jsr	r5,getc; 0:..
+	rts	r5
+
+putc:
+	mov	r1,-(sp)
+	mov	(r5)+,r1
+	dec	2(r1)
+	bge	1f
+	mov	r0,-(sp)
+	jsr	pc,flush1
+	mov	(sp)+,r0
+1:
+	movb	r0, at 4(r1)
+	inc	4(r1)
+	mov	(sp)+,r1
+	rts	r5
+
+flush:
+	mov	r0,-(sp)
+	mov	r1,-(sp)
+	mov	(r5)+,r1
+	jsr	pc,flush1
+	mov	(sp)+,r1
+	mov	(sp)+,r0
+	rts	r5
+
+flush1:
+	mov	r1,r0
+	add	$6,r0
+	mov	r0,-(sp)
+	mov	r0,0f
+	neg	r0
+	add	4(r1),r0
+	ble	1f
+	mov	r0,0f+2
+	mov	(r1),r0
+	sys	write; 0:..; 0:..
+1:
+	mov	(sp)+,4(r1)
+	mov	$127.,2(r1)
+	rts	pc
+
+fin:	.=.+2
+blkno:	-1
+nleft:	.=.+2
+loc:	inbuf
+lineptr: .=.+4
+line:	.=.+200.
+	.even
+lines:	.=.+2000.
+	.=.+3722.
+inbuf:	.=.+512.
+obuf:	.=.+134.
diff --git a/cmd/stat.s b/cmd/stat.s
new file mode 100644
index 0000000..ae10229
--- /dev/null
+++ b/cmd/stat.s
@@ -0,0 +1,298 @@
+/ stat -- print file status
+
+	mov	sp,r5
+	sys	open; 1:..; 0
+	bec	1f
+	sys	read; stbuf; 512.
+	add	r0,uids
+1:
+	mov	(r5)+,r0
+	mov	r0,argc
+	mov	r0,argv
+	cmp	r0,$2
+	beq	1f
+	jsr	r3,mesg; <argc\0>
+1:
+	tst	(r5)+
+	cmp	argc,$2
+	bge	1f
+	sys	exit
+1:
+	dec	argc
+	mov	(r5)+,0f
+	sys	stat; 0:..; stbuf
+	bec	1f
+	mov	0b,0f
+	jsr	r3,mesg; 0:..
+	jsr	r3,mesg; <?\n\0>
+	br	1b
+1:
+	mov	$stbuf,r4
+	mov	(r4)+,r2
+	jsr	r3,prdec; 3
+	jsr	r3,mesg; <  inode  mode  nl uid    size  t.mod.\n\0>
+	bit	$10000,(r4)
+	beq	2f
+	jsr	r3,putc; <l\0>
+	br	3f
+2:
+	jsr	r3,putc; <s\0>
+3:
+	bit	$40000,(r4)
+	beq	4f
+	jsr	r3,putc; <d\0>
+	br	5f
+4:
+	jsr	r3,putc; <-\0>
+5:
+	bit	$40,(r4)
+	beq	6f
+	jsr	r3,putc; <u\0>
+	br	7f
+6:
+	bit	$20,(r4)
+	beq	8f
+	jsr	r3,putc; <x\0>
+	br	7f
+8:
+	jsr	r3,putc; <-\0>
+7:
+	bit	$10,(r4)
+	beq	9f
+	jsr	r3,putc; <r\0>
+	br	10f
+9:
+	jsr	r3,putc; <-\0>
+10:
+	bit	$4,(r4)
+	beq	11f
+	jsr	r3,putc; <w\0>
+	br	12f
+11:
+	jsr	r3,putc; <-\0>
+12:
+	bit	$2,(r4)
+	beq	13f
+	jsr	r3,putc; <r\0>
+	br	14f
+13:
+	jsr	r3,putc; <-\0>
+14:
+	bit	$1,(r4)+
+	beq	15f
+	jsr	r3,putc; <w\0>
+	br	16f
+15:
+	jsr	r3,putc; <-\0>
+16:
+	jsr	r3,mesg; <  \0>
+	movb	(r4)+,r2
+	jsr	r3,prdec; 2
+	movb	(r4)+,r2
+	jsr	pc,pruid
+	mov	(r4)+,r2
+	jsr	r3,prdec; 5
+	jsr	r3,mesg; <  \0>
+	add	$20.,r4
+	mov	(r4)+,r2
+	mov	(r4)+,mq
+	mov	r2,ac
+	mov	$1,r0
+	jsr	pc,prdate
+	jsr	r3,mesg; <  \0>
+	mov	-2(r5),0f
+	jsr	r3,mesg; 0:..
+	jsr	r3,mesg; <\n\0>
+	jmp	1b
+
+pruid:
+	mov	$stbuf+22.,r1
+	cmp	r1,uids
+	bcc	1f
+	mov	r1,0f
+2:
+	tstb	(r1)+
+	beq	3f
+	cmpb	-1(r1),$':
+	bne	2b
+	clrb	-1(r1)
+3:
+	clr	mq
+	movb	(r1)+,r0
+	sub	$'0,r0
+	cmp	r0,$9.
+	bhi	4f
+	mov	$10.,mul
+	add	r0,mq
+	br	3b
+4:
+	cmp	mq,r2
+	bne	1f
+	jsr	r3,mesg; <  \0>
+	jsr	r3,mesg; 0:..
+	mov	0b,r1
+	mov	$6,-(sp)
+5:
+	tstb	(r1)+
+	beq	6f
+	dec	(sp)
+	br	5b
+6:
+	jsr	r3,mesg; <  \0>
+	dec	(sp)
+	bgt	6b
+	tst	(sp)+
+	emt	7
+	jsr	r3,mesg; <  \0>
+	jsr	r3,prdec; 3
+	jsr	r3,mesg; <\n\0>
+	emt	7
+
+putc:
+	mov	(r3)+,0f
+	mov	$1,r0
+	sys	write; 0:..; 1
+	emt	3
+
+mesg:
+	mov	r2,-(sp)
+	mov	(r3),r1
+	clr	r2
+1:
+	tstb	(r1)+
+	beq	2f
+	inc	r2
+	br	1b
+2:
+	mov	(r3)+,0f
+	mov	r2,0f+2
+	mov	$1,r0
+	sys	write; 0:..; 0:..
+	mov	(sp)+,r2
+	emt	3
+
+prdec:
+	mov	$6,r1
+	mov	$stbuf+22.,r0
+1:
+	mov	r2,mq
+	clr	ac
+	mov	$10.,div
+	add	$'0,ac
+	movb	ac,-(r0)
+	clr	ac
+	dec	r1
+	bne	1b
+	cmp	r0,$stbuf+21.
+	beq	2f
+	cmpb	(r0),$'0
+	bne	2f
+	movb	$' ,(r0)+
+	br	2b-4
+2:
+	mov	$stbuf+22.,0f
+	sub	(r3),0f
+	mov	(r3)+,0f+2
+	mov	$1,r0
+	sys	write; 0:..; 0:..
+	emt	3
+
+1:	</etc/uids\0>
+	.even
+uids:	stbuf+22.
+
+prdate:
+	mov	r1,-(sp)
+	sub	$16.,sp
+	mov	r0,r1
+	mov	sp,r0
+	jsr	pc,fmtdate
+	mov	r0,0f
+	mov	r1,r0
+	sys	write; 0:..; 17.
+	add	$16.,sp
+	mov	(sp)+,r1
+	rts	pc
+
+fmtdate:
+	mov	r2,-(sp)
+	mov	r3,-(sp)
+	cmp	ac,yrdays
+	blo	1f
+	bhi	2f
+	cmp	mq,yrdays+2
+	blo	1f
+2:
+	mov	ac,-(sp)
+	sub	yrdays+2,mq
+	sbc	(sp)
+	sub	yrdays,(sp)
+	mov	(sp)+,ac
+	mov	$29.,daylen
+1:
+	mov	$-4,lsh
+	mov	$26300.,div
+	mov	mq,r3
+	mov	ac,mq
+	mov	$2,lsh
+	mov	$17.,div
+	add	$17.,r0
+	jsr	r5,digit; 10.
+	jsr	r5,digit; 6
+	movb	$':,-(r0)
+	jsr	r5,digit; 10.
+	jsr	r5,digit; 6
+	movb	$':,-(r0)
+	mov	r3,mq
+	mov	$24.,div
+	mov	mq,r3
+	mov	ac,mq
+	jsr	r5,digit; 10.
+	jsr	r5,digit; 10.
+	mov	$montab,r2
+1:
+	cmp	(r2),r3
+	bgt	2f
+	sub	(r2)+,r3
+	br	1b
+2:
+	movb	$' ,-(r0)
+	sub	$montab,r2
+	asl	r2
+	add	$months,r2
+	inc	r3
+	mov	r3,mq
+	jsr	r5,digit; 10.
+	tst	mq
+	beq	1f
+	add	$'0,mq
+	movb	mq,-(r0)
+	br	2f
+1:
+	movb	$' ,-(r0)
+2:
+	movb	$' ,-(r0)
+	movb	-(r2),-(r0)
+	movb	-(r2),-(r0)
+	movb	-(r2),-(r0)
+	mov	(sp)+,r3
+	mov	(sp)+,r2
+	rts	pc
+
+digit:
+	clr	ac
+	mov	(r5)+,div
+	add	$'0,ac
+	movb	ac,-(r0)
+	rts	r5
+
+yrdays:	57544.; 4480.
+daylen:	31.; 28.; 31.; 30.; 31.; 30.; 31.; 31.; 30.; 31.; 30.
+montab = .-2
+months:
+	<   \0Jan\0Feb\0Mar\0Apr\0May\0Jun\0Jul\0Aug\0Sep\0Oct\0Nov\0Dec\0>
+	.even
+
+argc:	.=.+2
+argv:	.=.+2
+stbuf:	.=.+40.
diff --git a/cmd/tap.s b/cmd/tap.s
new file mode 100644
index 0000000..6d4727f
--- /dev/null
+++ b/cmd/tap.s
@@ -0,0 +1,666 @@
+/ tap -- tape archiver
+
+	br	start
+	07136
+	0
+	0
+
+	ble	1f
+	0
+
+start:
+	sys	stat; 0; 0
+	mov	(sp),argc
+	mov	(sp)+,argc2
+	mov	$tapdev,path
+	incb	tapname+8.
+	tst	(sp)+
+	cmp	argc2,$2
+	bge	1f
+	mov	$2,argc2
+	br	main
+1:
+	mov	(sp)+,r0
+	mov	sp,argp
+	movb	(r0)+,r1
+	beq	main
+	mov	$optbl,r2
+1:
+	cmp	r1,(r2)+
+	beq	2f
+	tst	(r2)+
+	bne	1b
+	br	baduse
+2:
+	jsr	pc,@(r2)+
+	br	1b
+
+main:
+	sys	intr; 0
+	jsr	pc,topen
+	incb	moession
+	sys	chmod; tapdev; 0
+	mov	$dir,r4
+	jmp	@path
+
+topen:
+	sys	open; tapdev; 0
+	bes	opnerr
+	mov	r0,tfi
+	sys	open; tapdev; 1
+	bes	opnerr
+	mov	r0,tfo
+	sys	stat; tapdev; stbuf
+	bit	$1,stbuf+2
+	beq	opnerr
+	rts	pc
+
+opnerr:
+	jsr	r5,mesg
+	<Tape open error\0>
+	.even
+	jmp	done
+
+setpath:
+	cmp	path,$tapdev
+	bne	baduse
+	mov	(r5)+,path
+	rts	r5
+
+chknull:
+	mov	(r5)+,r0
+	beq	1f
+	tstb	(r0)
+	beq	chknull
+	br	baduse
+1:
+	rts	r5
+
+baduse:
+	jsr	r5,mesg
+	<Bad usage\0>
+	.even
+	jmp	done
+
+optbl:
+	'0; setdv
+	'1; setdv
+	'2; setdv
+	'3; setdv
+	'4; setdv
+	'5; setdv
+	'6; setdv
+	'7; setdv
+	'c; docr
+	'd; dodel
+	'f; dofil
+	'l; dolist
+	'm; domkd
+	'r; dorepl
+	't; dotbl
+	'u; doupd
+	'v; dover
+	'w; dowrt
+	'x; doextr
+	0; 0
+
+setdv:
+	movb	r1,tapname+8.
+	rts	pc
+
+dodel:
+	incb	dession
+	rts	pc
+
+dofil:
+	incb	fession
+	rts	pc
+
+docr:
+	jsr	r5,setpath; tapdev
+	rts	pc
+
+domkd:
+	incb	moession
+	rts	pc
+
+doupd:
+	incb	uession
+	jsr	r5,setpath; tapdev
+	rts	pc
+
+dorepl:
+	clrb	uession
+	jsr	r5,setpath; tapdev
+	rts	pc
+
+dotbl:
+	incb	tession
+	jsr	r5,setpath; tapstr
+	rts	pc
+
+dover:
+	incb	vession
+	rts	pc
+
+dowrt:
+	incb	wession
+	rts	pc
+
+doextr:
+	jsr	r5,setpath; fpath
+	rts	pc
+
+/ table of contents
+dottab:
+	.=.+512.
+
+/ directory reading
+dotab:
+	jsr	r5,chknull; mnp; nnp; pnp; 0
+	cmp	argc2,$2
+	bgt	1f
+	jmp	baduse
+1:
+	jsr	pc,readdir
+	jsr	r5,match; dir2
+	jsr	pc,readtape
+	br	endtab
+
+doread:
+	jsr	r5,chknull; pnp; 0
+	tstb	dession
+	beq	1f
+	jsr	pc,cleardir
+	br	2f
+1:
+	jsr	pc,readdir
+2:
+	jsr	pc,readtape
+	jsr	pc,prstat
+	jsr	pc,prdir
+	br	endtab
+
+domake:
+	jsr	r5,chknull; mnp; nnp; 0
+	jsr	r5,namecpy; dir2; nname
+	jsr	pc,readdir
+	jsr	r5,match; dir2
+	br	endmak
+
+doupdt:
+	jsr	r5,chknull; mnp; nnp; pnp; snp; rnp; 0
+	jsr	r5,namecpy; dir2; nname
+	jsr	pc,readdir
+	jsr	r5,match; dir2
+	jsr	pc,doproc
+	tstb	tession
+	beq	prhdr
+	jsr	r5,mesg
+	<MODE  UID SIZE  TAPA    DATE     NAME\0>
+	.even
+prhdr:
+	jsr	r5,match; dir2
+	br	endprc
+
+endtab:
+	mov	$dir,r4
+	jsr	pc,readdir
+	jsr	pc,prtape
+endmak:
+	jsr	pc,doproc
+	jsr	r5,mesg; <END\0>; .even
+
+done:
+	sys	exit
+
+doproc:
+	tstb	moession
+	beq	1f
+	sys	chmod; tapdev; 017
+	mov	tfi,r0
+	sys	close
+	mov	tfo,r0
+	sys	close
+	clrb	moession
+	sys	intr; 1
+1:
+	rts	pc
+
+namecpy:
+	mov	(r5)+,r0
+	mov	$dir2,r1
+1:
+	mov	(r0)+,(r1)+
+	cmp	r0,(r5)
+	bcs	1b
+	cmp	r1,$dir2+512.
+	blos	1f
+	jsr	r5,mesg; <Overlay error\0>; .even
+	iot
+1:
+	tst	(r5)+
+	rts	r5
+
+npath:
+	mov	r3,-(sp)
+	mov	r2,-(sp)
+	mov	r1,-(sp)
+	mov	(r5),r2
+	mov	r2,r1
+	bicb	$177600,(r2)
+	cmpb	(r2),$'/
+	bne	1f
+	jsr	pc,findent
+	inc	r2
+	br	.-10
+1:
+	tstb	(r2)+
+	bne	.-4
+	mov	r4, at 0(sp)
+	mov	(r5)+,r2
+	mov	r2,r1
+	cmpb	(r2),$'/
+	bne	2f
+	jsr	pc,findent
+	movb	r0,(r4)+
+	inc	r2
+	br	.-14
+2:
+	tstb	(r2)+
+	bne	.-4
+	movb	(r1)+,(r4)+
+	bne	.-4
+	mov	(sp)+,r1
+	mov	(sp)+,r2
+	mov	(sp)+,r3
+	rts	r5
+
+findent:
+	mov	$dir,r3
+	mov	$200,-(sp)
+	cmp	r3,r4
+	bcc	newent
+	cmpb	(r3)+,$200
+	bne	.-6
+	inc	(sp)
+	mov	r1,r0
+	cmpb	(r3),$200
+	beq	.-12
+	cmp	r0,r2
+	bcc	1f
+	cmpb	(r0)+,(r3)+
+	beq	.-10
+	br	.-22
+1:
+	tstb	(r3)
+	bne	.-24
+	br	2f
+
+newent:
+	movb	$200,(r4)+
+	inc	(sp)
+	mov	r1,r0
+	cmp	r0,r2
+	bcc	1f
+	movb	(r0)+,(r4)+
+	br	.-6
+1:
+	clrb	(r4)+
+2:
+	mov	(sp)+,r0
+	rts	pc
+
+epath:
+	mov	r3,-(sp)
+	mov	r2,-(sp)
+	mov	r1,-(sp)
+	mov	(r1),r1
+	mov	(r5)+,r2
+	movb	(r1)+,r0
+	beq	3f
+	blt	1f
+	movb	r0,(r2)+
+	br	.-10
+1:
+	mov	$dir,r3
+	bic	$177600,r0
+	cmpb	(r3)+,$200
+	bne	.-4
+	dec	r0
+	bne	.-4
+	movb	(r3)+,(r2)+
+	bne	.-4
+	movb	$'/,-1(r2)
+	br	epath+16.
+3:
+	clrb	(r2)+
+	mov	(sp)+,r1
+	mov	(sp)+,r2
+	mov	(sp)+,r3
+	rts	r5
+
+tapdev:	</dev/tap0\0>
+	.even
+
+/ message subroutine
+prints:
+	movb	(r1)+,r0
+	beq	1f
+	jsr	pc,putc
+	br	prints
+1:
+	rts	pc
+
+mesg:
+	movb	(r5)+,r0
+	beq	1f
+	jsr	pc,putc
+	br	mesg
+1:
+	inc	r5
+	bic	$1,r5
+	rts	r5
+
+putc:
+	movb	r0,ch
+	mov	$1,r0
+	sys	write; ch; 1
+	rts	pc
+
+getc:
+	clr	r0
+	sys	read; ch; 1
+	movb	ch,r0
+	rts	pc
+
+cleardir:
+	mov	$dir2,r1
+	mov	$192.,r2
+	jsr	pc,1f
+	dec	r2
+	bne	.-4
+	rts	pc
+1:
+	clr	(r1)+
+	clr	(r1)+
+	clr	(r1)+
+	clr	(r1)+
+	clr	(r1)+
+	clr	(r1)+
+	clr	(r1)+
+	clr	(r1)+
+	rts	pc
+
+readdir:
+	mov	tfi,r0
+	sys	read; dir; 512.
+	mov	$dir,r4
+	add	r0,r4
+	rts	pc
+
+readtape:
+	mov	tfi,r0
+	sys	read; tbuf; 512.
+	jsr	pc,chksum
+	bne	csumerr
+	rts	pc
+
+chksum:
+	mov	$tbuf,r0
+	clr	r1
+1:
+	add	(r0)+,r1
+	cmp	r0,$tbuf+512.
+	bne	1b
+	tst	r1
+	rts	pc
+
+csumerr:
+	jsr	r5,mesg
+	<Directory checksum\0>
+	.even
+	jmp	done
+
+rderr:
+	jsr	r5,mesg
+	<Tape read error\0>
+	.even
+	jmp	done
+
+wrterr:
+	jsr	r5,mesg
+	<Tape write error\0>
+	.even
+	jmp	done
+
+seekerr:
+	jsr	r5,mesg
+	<Tape seek error\0>
+	.even
+	jmp	done
+
+match:
+	mov	r3,-(sp)
+	mov	r2,-(sp)
+	mov	r1,-(sp)
+	mov	(r5)+,r1
+	mov	$dir,r2
+1:
+	cmp	r2,r4
+	bcc	2f
+	tstb	(r2)+
+	beq	1b
+	jsr	pc,cmpmatch
+	beq	3f
+	br	1b
+2:
+	mov	$-1,r0
+	br	4f
+3:
+	mov	r2,r0
+	sub	$dir,r0
+4:
+	mov	(sp)+,r1
+	mov	(sp)+,r2
+	mov	(sp)+,r3
+	rts	r5
+
+cmpmatch:
+	mov	r1,-(sp)
+1:
+	cmpb	(r1)+,(r2)+
+	bne	2f
+	tstb	-1(r1)
+	bne	1b
+	clr	r0
+	br	3f
+2:
+	mov	$1,r0
+3:
+	mov	(sp)+,r1
+	rts	pc
+
+prtape:
+	jsr	r5,mesg
+	< entries\0>
+	.even
+	rts	pc
+
+prstat:
+	jsr	r5,mesg
+	< used\0>
+	.even
+	rts	pc
+
+prdir:
+	jsr	r5,mesg
+	< free\0>
+	.even
+	rts	pc
+
+prfree:
+	jsr	r5,mesg
+	< last\0>
+	.even
+	rts	pc
+
+prdec:
+	clr	ac
+	mov	(r5)+,div
+	add	$'0,ac
+	movb	ac,-(r1)
+	rts	r5
+
+prmon:
+	jsr	r5,prdec; 10.
+	cmp	r0,$2
+	beq	1f
+	mov	(r5)+,r0
+	jsr	pc, at putca
+	rts	r5
+1:
+	mov	$'-,r0
+	jsr	pc, at putca
+	tst	(r5)+
+	rts	r5
+
+prdiv:
+	clr	ac
+	mov	(r5)+,div
+	add	$'0,ac
+	movb	ac,-(r1)
+	rts	r5
+
+/ archive file routines
+dofile:
+	mov	4(r1),r3
+	beq	2f
+	mov	12.(r1),r0
+	jsr	pc,setwrt
+	sys	creat; wrbuf; 0
+	bes	1f
+	mov	r0,r2
+	cmp	r3,$512.
+	bcs	3f
+	jsr	pc,rdbuf
+	mov	r2,r0
+	sys	write; dbuf; 512.
+	bes	1f
+	cmp	r0,$512.
+	bne	1f
+	sub	$512.,r3
+	br	.-30
+3:
+	mov	r3,0f
+	beq	4f
+	jsr	pc,rdbuf
+	mov	r2,r0
+	sys	write; dbuf; 0:..
+	bes	1f
+	cmp	r0,.-6
+	bne	1f
+4:
+	mov	r2,r0
+	sys	close
+	movb	3(r1),0f
+	sys	chown; wrbuf; 0:..
+	movb	2(r1),0f
+	sys	chmod; wrbuf; 0:..
+	mov	10.(r1),mq
+	mov	6(r1),ac
+	sys	smdate; wrbuf
+2:
+	rts	pc
+1:
+	tstb	@$pnp
+	beq	2f
+	jsr	r5,mkmiss
+	br	dofile+6
+2:
+	clr	mq
+	sys	smdate; wrbuf
+	mov	r2,r0
+	sys	close
+opnerr2:
+	mov	$wrbuf,r1
+	jsr	pc,prints
+	jsr	r5,mesg
+	< -- create error\n\0>
+	.even
+	rts	pc
+
+mkmiss:
+	jsr	r5,mesg
+	< not found\0>
+	.even
+	rts	pc
+
+phaserr:
+	jsr	r5,mesg
+	< -- Phase error\0>
+	.even
+	rts	pc
+
+ovflerr:
+	jsr	r5,mesg
+	<Tape overflow\0>
+	.even
+	jmp	done
+
+rdbuf:
+	mov	tfi,r0
+	sys	read; dbuf; 512.
+	rts	pc
+
+wrbuf:
+	.=.+32.
+	.even
+setwrt:
+	mov	r0,0f
+	sys	open; 0:..; 0
+	rts	pc
+
+putca:
+	putc
+
+/ EAE registers
+div = 177300
+ac = 177302
+mq = 177304
+
+month:	<JanFebMarAprMayJunJulAugSepOctNovDec\0>
+	.even
+
+tapstr:	</bin/mkdir\0>
+	.even
+fpath:	.=.+32.
+	.even
+
+.bss
+ch:	.=.+2
+argc:	.=.+2
+argc2:	.=.+2
+argp:	.=.+2
+path:	.=.+2
+tfi:	.=.+2
+tfo:	.=.+2
+dession: .=.+2
+fession: .=.+2
+moession: .=.+2
+tession: .=.+2
+uession: .=.+2
+vession: .=.+2
+wession: .=.+2
+tapname: .=.+16.
+stbuf:	.=.+36.
+dir:	.=.+1024.
+dir2:	.=.+1024.
+tbuf:	.=.+512.
+dbuf:	.=.+512.
+nname:	.=.+64.
+mnp:	.=.+2
+nnp:	.=.+2
+pnp:	.=.+2
+snp:	.=.+2
+rnp:	.=.+2
diff --git a/cmd/tm.s b/cmd/tm.s
new file mode 100644
index 0000000..b2dbec3
--- /dev/null
+++ b/cmd/tm.s
@@ -0,0 +1,284 @@
+/ tm -- system timing utility
+
+	br	start
+	beq	1f
+	0
+	0
+
+	bge	1f
+	0
+
+start:
+	sys	open; timfil; 0
+	bes	notime
+	mov	r0,r1
+	sys	read; tbuf; 26.
+	mov	r1,r0
+	sys	close
+	br	1f
+
+notime:
+	sys	time
+	mov	ac,ovrd
+	mov	mq,ovrd+2
+1:
+	sys	creat; timfil; 017
+	bec	1f
+	jsr	r5,mesg
+	<cannot create time file.\0>
+	.even
+1:
+	sys	exit
+
+timeerr:
+	mov	r0,r2
+	sys	open; sbfil; 0
+	bec	1f
+	jsr	r5,mesg
+	<cannot open super-block.\0>
+	.even
+1:
+	sys	exit
+
+openerr:
+	mov	r0,r1
+	sys	read; sbuf; 1024.
+	mov	r1,r0
+	sys	close
+	mov	ovrd,dsk+2
+	mov	ovrd+2,dsk+4
+	mov	r2,r0
+	sys	write; sbuf+6; 26.
+	mov	r2,r0
+	sys	close
+	cmp	(sp),$1
+	blos	prstats
+	jsr	pc,argproc
+	clr	(sp)
+	br	start
+
+prstats:
+	mov	$tbuf,r1
+	mov	$sbuf+6,r2
+	jsr	r5,mesg; <tim\0>; .even
+	jsr	pc,prline
+	jsr	r5,mesg; <ovh\0>; .even
+	jsr	pc,prline
+	jsr	r5,mesg; <dsk\0>; .even
+	jsr	pc,prline
+	jsr	r5,mesg; <idl\0>; .even
+	jsr	pc,prline
+	jsr	r5,mesg; <usr\0>; .even
+	jsr	pc,prline
+	tst	(sp)
+	beq	done
+	jsr	r5,mesg; <der \0>; .even
+	movb	(r2),r0
+	bic	$177400,r0
+	jsr	pc,prdec
+	jsr	r5,mesg; <,\0>; .even
+	movb	1(r2),r0
+	bic	$177400,r0
+	jsr	pc,prdec
+	jsr	r5,mesg; <  \0>; .even
+1:
+	sub	(r1),(r2)
+	movb	(r2)+,r0
+	bic	$177400,r0
+	jsr	pc,prdec
+	jsr	r5,mesg; <,\0>; .even
+	movb	(r2)+,r0
+	bic	$177400,r0
+	jsr	pc,prdec
+	jsr	r5,mesg; <\n\0>; .even
+
+done:
+	sys	exit
+
+dofork:
+	sys	fork
+	br	1f
+	bec	1f
+1:
+	sys	wait
+	rts	pc
+
+argproc:
+	tst	(sp)+
+	mov	(sp)+,r0
+	tst	(sp)+
+	mov	$tbuf,r1
+	mov	$argv,r2
+	sys	stat; argv; argp
+	mov	(sp)+,r3
+	mov	r2,(r1)+
+1:
+	movb	(r3)+,(r2)+
+	bne	1b
+	dec	r0
+	cmp	r0,$1
+	bgt	1b
+	clr	(r1)+
+	sys	utime
+	sys	fstat
+	sys	exec; argv; tbuf
+	mov	$binsh,dexec
+	mov	$<bi>,dexec+2
+	mov	$</n>,dexec+4
+	sys	exec; binsh; tbuf
+	jsr	r5,mesg; <?\0>; .even
+
+done2:
+	sys	exit
+
+prtnum:
+	mov	$nbuf+3,r4
+	mov	r0,mq
+	jsr	r5,digit; 10.
+	jsr	r5,digit; 10.
+	jsr	r5,digit; 10.
+	jsr	r5,digit; 10.
+	cmpb	(r4),$'0
+	bne	1f
+	movb	$' ,(r4)+
+	cmp	r4,$nbuf+5
+	bne	.-10
+1:
+	mov	$1,r0
+	sys	write; nbuf+2; 4
+	rts	pc
+
+prline:
+	tst	2(sp)
+	beq	2f
+	jsr	r5,mesg; < \0>; .even
+	mov	2(r2),mq
+	cmp	r2,$sbuf+6
+	bne	1f
+	mov	(r2),-(sp)
+	sub	ovrd+2,mq
+	sbc	(sp)
+	sub	ovrd,(sp)
+	mov	(sp)+,ac
+	br	3f
+1:
+	mov	(r2),ac
+3:
+	jsr	pc,prdiv
+2:
+	sub	2(r1),2(r2)
+	sbc	(r2)
+	sub	(r1),(r2)
+	mov	2(r2),mq
+	mov	(r2),ac
+	jsr	pc,prdiv
+	mov	dsk,mq
+	mov	$6,div
+	add	$'0,mq
+	movb	mq,11(r4)
+	jsr	r5,digit; 10.
+	br	4f
+	movb	$':',(r4)
+4:
+	jsr	r5,digit; 10.
+	br	5f
+	movb	$':',(r4)
+5:
+	jsr	r5,digit; 10.
+	jsr	r5,digit; 10.
+	jsr	r5,digit; 10.
+	cmpb	(r4),$'0
+	beq	1f
+	cmpb	(r4),$':
+	bne	2f
+1:
+	movb	$' ,(r4)+
+	cmp	r4,$nbuf+2
+	bne	.-16
+2:
+	mov	$1,r0
+	sys	write; nbuf+2; 9
+	rts	pc
+
+prdiv:
+	mov	$7020,div
+	mov	mq,r3
+	mov	ac,mq
+	clr	ac
+	mov	$'<,div
+	mov	ac,dsk
+	mov	$nbuf+3,r4
+	jsr	r5,digit; 10.
+	jsr	r5,digit; 6
+	movb	$':',(r4)
+	mov	r3,mq
+	jsr	r5,digit; 10.
+	jsr	r5,digit; 10.
+	jsr	r5,digit; 10.
+	cmpb	(r4),$'0
+	beq	1f
+	cmpb	(r4),$':
+	bne	2f
+1:
+	movb	$' ,(r4)+
+	cmp	r4,$nbuf+2
+	bne	.-16
+2:
+	mov	$1,r0
+	sys	write; nbuf+2; 9
+	rts	pc
+
+digit:
+	clr	ac
+	mov	(r5)+,div
+	add	$'0,ac
+	movb	ac,-(r4)
+	rts	r5
+
+mesg:
+	movb	(r5)+,ch
+	beq	1f
+	mov	$1,r0
+	sys	write; ch; 1
+	br	mesg
+1:
+	inc	r5
+	bic	$1,r5
+	rts	r5
+
+prdec:
+	clr	ac
+	mov	$10.,div
+	mov	ac,-(sp)
+	tst	mq
+	beq	1f
+	jsr	pc,prdec
+1:
+	add	$'0,(sp)
+	mov	(sp)+,ch
+	mov	$1,r0
+	sys	write; ch; 1
+	rts	pc
+
+timfil:	</tmp/tm\0>
+tmpfil:	</tmp/tmp\0>
+devrf0:	</dev/rf0\0>
+	.even
+
+.bss
+ch:	.=.+2
+ovrd:	.=.+4
+dsk:	.=.+4
+tbuf:	.=.+32.
+sbuf:	.=.+1024.
+nbuf:	.=.+16.
+argv:	.=.+64.
+argp:	.=.+32.
+binsh:	.=.+16.
+dexec:	.=.+8.
+sbfil:	.=.+16.
+
+/ EAE registers
+div = 177300
+ac = 177302
+mq = 177304
diff --git a/cmd/un.s b/cmd/un.s
new file mode 100644
index 0000000..53f565a
--- /dev/null
+++ b/cmd/un.s
@@ -0,0 +1,79 @@
+/ un -- print undefined symbols from a.out
+
+	cmp	(sp)+,$2
+	blt	1f
+	tst	(sp)+
+	mov	(sp)+,0f
+1:
+	sys	open; 0:..; 0
+	bes	error
+	mov	r0,r1
+	sys	read; hdr; 16.
+	cmp	r0,$16.
+	bne	error
+	cmp	hdr,$407
+	bne	error
+	mov	hdr+2,r2
+	add	hdr+4,r2
+	cmp	hdr+14.,$1
+	beq	1f
+	asl	r2
+1:
+	add	$16.,r2
+	mov	r2,0f
+	mov	r1,r0
+	sys	seek; 0:..; 0
+	add	hdr+6.,0f
+	sys	seek; 0f+2; 0
+loop:
+	mov	r1,r0
+	sys	read; sym; 12.
+	mov	$sym,r1
+	mov	r1,r2
+	add	r0,r2
+	cmp	r1,r2
+	blo	1f
+	tst	filter
+	beq	2f
+	sys	exit
+2:
+	mov	$' ,filter
+	mov	$sym,r1
+	br	loop
+1:
+	cmp	filter,8.(r1)
+	bne	next
+	mov	r1,r3
+	mov	$name,r4
+	mov	$8.,r5
+	bit	$40,8.(r1)
+	beq	3f
+	movb	$'_,(r4)+
+	movb	$'\b,(r4)+
+3:
+	movb	(r3)+,(r4)+
+	beq	4f
+	dec	r5
+	bne	3b
+4:
+	movb	$'\n,(r4)+
+	sub	$name,r4
+	mov	r4,0f
+	mov	$1,r0
+	sys	write; name; 0:..
+next:
+	add	$12.,r1
+	br	loop
+
+error:
+	mov	$1,r0
+	sys	write; errmsg; 2
+	sys	exit
+errmsg:	<?\n>
+
+0:	<a.out\0>
+	.even
+filter:	.=.+2
+hdr:	.=.+16.
+sym:	.=.+12.
+name:	.=.+16.
diff --git a/cmd/wc.s b/cmd/wc.s
new file mode 100644
index 0000000..7a115cd
--- /dev/null
+++ b/cmd/wc.s
@@ -0,0 +1,180 @@
+/ wc -- word count
+
+	mov	(sp)+,nfiles
+	tst	(sp)+
+	dec	nfiles
+	ble	done
+
+loop:
+	br	1f
+2:
+	mov	buf,r0
+	sys	close
+	dec	nfiles
+	beq	done
+1:
+	clr	words
+	clr	lines
+	clr	text
+	clr	ctrl
+	mov	$1,inflag
+	mov	(sp),r0
+	jsr	r5,fopen; buf
+	bes	error
+	jsr	r5,getc; buf
+	bes	pline
+	cmpb	$'\n,r0
+	bne	1f
+	inc	lines
+	inc	inflag
+	br	2f
+
+1:
+	cmpb	$' ,r0
+	beq	3f
+	cmpb	$'\t,r0
+	bne	4f
+3:
+	clr	inflag
+2:
+	tst	ctrl
+	bne	gchar
+	inc	ctrl
+	inc	words
+	br	gchar
+
+4:
+	cmpb	$'.,r0
+	bne	5f
+	tst	inflag
+	beq	gchar
+	inc	text
+	jsr	r5,getc; buf
+	cmpb	$'\n,r0
+	bne	4b
+	br	gchar
+
+5:
+	clr	inflag
+	clr	ctrl
+gchar:
+	br	2b
+
+pline:
+	jsr	r5,mesg; <\n  file: \0>; .even
+	mov	(sp)+,r0
+	jsr	r5,mesg; 0:..; .even
+	jsr	r5,mesg; < \0>; .even
+	jsr	r5,decml; text
+	jsr	r5,mesg; < text lines\n\0>; .even
+	jsr	r5,decml; words
+	jsr	r5,mesg; < control lines\n\0>; .even
+	jsr	r5,decml; lines
+	jsr	r5,mesg; <  lines\n\0>; .even
+	jmp	loop
+
+done:
+	sys	exit
+
+mesg:
+	mov	(r5)+,r1
+	mov	r1,r2
+	mov	r1,0f
+1:
+	tstb	(r1)+
+	bne	1b
+	sub	r2,r1
+	mov	r1,0f+2
+	mov	$1,r0
+	sys	write; 0:..; 0:..
+	rts	r5
+
+decml:
+	mov	@(r5)+,mq
+	mov	$1,r0
+	jsr	pc,1f
+	rts	r5
+1:
+	clr	ac
+	mov	$10.,div
+	mov	ac,-(sp)
+	tst	mq
+	beq	2f
+	jsr	pc,1b
+2:
+	add	$'0,(sp)
+	mov	(sp)+,ch
+	sys	write; ch; 1
+	rts	pc
+
+fopen:
+	mov	r1,-(sp)
+	mov	(r5)+,r1
+	mov	r0,0f
+	sys	open; 0:..; 0
+	bec	1f
+	mov	$-1,(r1)
+	mov	(sp)+,r1
+	sec
+	rts	r5
+1:
+	mov	r0,(r1)+
+	clr	(r1)+
+	mov	(sp)+,r1
+	rts	r5
+
+getc:
+	mov	(r5),0f
+	mov	(r5)+,0f+2
+	jsr	r5,1f; 0:..
+	bec	2f
+	rts	r5
+2:
+	mov	r0,-(sp)
+	jsr	r5,1f; 0:..
+	swab	r0
+	bis	(sp)+,r0
+	rts	r5
+1:
+	mov	r1,-(sp)
+	mov	(r5)+,r1
+	dec	2(r1)
+	bge	3f
+	mov	r1,r0
+	add	$6,r0
+	mov	r0,0f
+	mov	r0,4(r1)
+	mov	(r1),r0
+	sys	read; 0:..; 512.
+	bec	4f
+4:
+	tst	r0
+	bne	5f
+	mov	(sp)+,r1
+	sec
+	rts	r5
+5:
+	dec	r0
+	mov	r0,2(r1)
+3:
+	clr	r0
+	bisb	@4(r1),r0
+	inc	4(r1)
+	mov	(sp)+,r1
+	rts	r5
+
+error:
+	mov	$1,r0
+	sys	write; quest; 2
+	sys	exit
+quest:	<?\n>
+
+inflag:	.=.+2
+
+ch:	.=.+2
+text:	.=.+2
+words:	.=.+2
+ctrl:	.=.+2
+lines:	.=.+2
+nfiles:	.=.+2
+buf:	.=.+518.
diff --git a/cmd/who.s b/cmd/who.s
new file mode 100644
index 0000000..0abe522
--- /dev/null
+++ b/cmd/who.s
@@ -0,0 +1,150 @@
+/ who -- who is logged in
+
+	cmp	(sp)+,$1
+	ble	1f
+	mov	2(sp),0f
+1:
+	sys	open; 0:..; 0
+	bes	error
+	mov	r0,r1
+2:
+	mov	r1,r0
+	sys	read; utmp; 16.
+	tst	r0
+	beq	done
+	tst	utmp
+	bne	3f
+	cmp	0b,$deffile
+	beq	2b
+	mov	$1,r0
+	sys	write; blank; 8.
+	br	4f
+3:
+	mov	$1,r0
+	sys	write; utmp; 8.
+4:
+	movb	utmp+8.,ttyno
+	cmp	0b,$deffile
+	bne	5f
+	mov	$1,r0
+	sys	write; ttyc; 3
+5:
+	mov	$1,r0
+	sys	write; spsp; 2
+	mov	utmp+12.,mq
+	mov	utmp+10.,ac
+	mov	$1,r0
+	jsr	pc,prdate
+	mov	$1,r0
+	sys	write; nl; 1
+	br	2b
+
+error:
+	mov	$1,r0
+	sys	write; errmsg; 2
+done:
+	sys	exit
+
+blank:	<        >
+ttyc:	<tty>
+ttyno = ttyc+3
+spsp:	<  >
+deffile:
+0:	</tmp/utmp\0>
+	.even
+nl:	<\n>
+utmp:	.=.+16.
+
+prdate:
+	mov	r1,-(sp)
+	sub	$16.,sp
+	mov	r0,r1
+	mov	sp,r0
+	jsr	pc,fmtdate
+	mov	r0,0f
+	mov	r1,r0
+	sys	write; 0:..; 17.
+	add	$16.,sp
+	mov	(sp)+,r1
+	rts	pc
+
+fmtdate:
+	mov	r2,-(sp)
+	mov	r3,-(sp)
+	cmp	ac,yrdays
+	blo	1f
+	bhi	2f
+	cmp	mq,yrdays+2
+	blo	1f
+2:
+	mov	ac,-(sp)
+	sub	yrdays+2,mq
+	sbc	(sp)
+	sub	yrdays,(sp)
+	mov	(sp)+,ac
+	mov	$29.,daylen
+1:
+	mov	$-4,lsh
+	mov	$26300.,div
+	mov	mq,r3
+	mov	ac,mq
+	mov	$2,lsh
+	mov	$17.,div
+	add	$17.,r0
+	jsr	r5,digit; 10.
+	jsr	r5,digit; 6
+	movb	$':,-(r0)
+	jsr	r5,digit; 10.
+	jsr	r5,digit; 6
+	movb	$':,-(r0)
+	mov	r3,mq
+	mov	$24.,div
+	mov	mq,r3
+	mov	ac,mq
+	jsr	r5,digit; 10.
+	jsr	r5,digit; 10.
+	mov	$montab,r2
+1:
+	cmp	(r2),r3
+	bgt	2f
+	sub	(r2)+,r3
+	br	1b
+2:
+	movb	$' ,-(r0)
+	sub	$montab,r2
+	asl	r2
+	add	$months,r2
+	inc	r3
+	mov	r3,mq
+	jsr	r5,digit; 10.
+	tst	mq
+	beq	1f
+	add	$'0,mq
+	movb	mq,-(r0)
+	br	2f
+1:
+	movb	$' ,-(r0)
+2:
+	movb	$' ,-(r0)
+	movb	-(r2),-(r0)
+	movb	-(r2),-(r0)
+	movb	-(r2),-(r0)
+	mov	(sp)+,r3
+	mov	(sp)+,r2
+	rts	pc
+
+digit:
+	clr	ac
+	mov	(r5)+,div
+	add	$'0,ac
+	movb	ac,-(r0)
+	rts	r5
+
+yrdays:	57544.; 4480.
+daylen:	31.; 28.; 31.; 30.; 31.; 30.; 31.; 31.; 30.; 31.; 30.
+montab = .-2
+months:
+	<   \0Jan\0Feb\0Mar\0Apr\0May\0Jun\0Jul\0Aug\0Sep\0Oct\0Nov\0Dec\0>
+	.even
+
+errmsg:	<?\n>
-- 
2.51.0



More information about the TUHS mailing list