V2/c/rt/libc.sa

mÿbsw.s¡šS
X	/ crt -- c runtime routines

.globl	retrn
.globl	bswitch
.globl	_getchar
.globl	_putchar
.globl	_flush
.globl	_fin
.globl	_fout

.globl	_main
.globl	getc
.globl	putc
.globl	flush

start:
	mov	$mq,r4
	mov	sp,r0
	mov	(r0),-(sp)
	tst	(r0)+
	mov	r0,2(sp)
	jsr	pc,*_main
	clr	r0
	sys	exit

retrn:
	mov	r5,sp
	mov	(sp)+,r5
	rts	pc

_getchar:.+2
1:
	jsr	r5,getc; _fin
	bcs	1f
	tst	r0
	beq	1b
	rts	pc
1:
	clr	r0
	rts	pc

_putchar:.+2
	mov	2(sp),r0
	tst	_fout
	bne	1f
	mov	$1,_fout
1:
	jsr	r5,putc; _fout
	movb	3(sp),r0
	beq	1f
	jsr	r5,putc; _fout
1:
	cmp	_fout,$1
	bne	1f
	jsr	r5,flush; _fout
1:
	mov	2(sp),r0
	rts	pc

_flush:
	.+2
	jsr	r5,flush; _fout
	rts	pc

bswitch:
	mov	*(sp),r1
	mov	r1,base
	mov	(r1),r2		/ low
	mov	(r1)+,r3	/ hi
	mov	$1,-(sp)	/ n
	tst	(r1)+
	bne	1f
	4			/ n = 0
1:
	tst	2(r1)
	beq	1f
	cmp	(r1),r2
	bhis	2f
	mov	(r1),r2
2:
	cmp	(r1)+,r3
	blo	2f
	mov	-2(r1),r3
2:
	tst	(r1)+
	inc	(sp)
	br	1b
1:
	sub	r2,r3		/ spread
	asl	(sp)
	inc	r3
	cmp	r3,(sp)
	blo	initd		/ if spread < 2*ncase direct

initb:
	clr	(sp)		/ flag
	mov	base,r2
	mov	r2,r3
	add	$4,r3
1:
	cmp	r3,r1
	bhis	1f
	cmp	(r2)+,(r3)+
	blos	2f
	mov	-(r2),-(sp)
	mov	-(r3),(r2)+
	mov	(sp)+,(r3)+
	mov	(r2),-(sp)
	mov	(r3),(r2)
	mov	(sp)+,(r3)
	inc	(sp)
2:
	cmp	(r2)+,(r3)+
	br	1b
1:
	tst	(sp)
	bne	initb
	cmp	(sp)+,(r1)+
	mov	r1,-(sp)
1:
	mov	-(r1),2(r1)
	cmp	r1,base
	bhi	1b
	mov	(sp)+,(r1)
	mov	$binary+4,r3
	br	init

initd:
	mov	(sp)+,r3
	mov	r3,twon
	mov	r3,twona
	mov	r2,-(sp)		/ low
	mov	r3,-(sp)		/ 2*n
1:
	mov	base,r3
2:
	cmp	(r3)+,r2
	beq	2f
	tst	(r3)+
	cmp	r3,r1
	blo	2b
	mov	(r1),-(sp)		/ no match, default
	br	3f
2:
	mov	(r3),-(sp)		/ match
3:
	inc	r2
	dec	twon
	bne	1b
	add	$4,r1
	add	$2,twona
1:
	mov	(sp)+,-(r1)
	dec	twona
	bne	1b
	mov	$direct+4,r3

init:
	mov	(sp)+,r2
	mov	-(r3),-(r2)
	mov	-(r3),-(r2)
	jmp	(r2)

direct:
	jsr	pc,*$1f


/	lowval; nval
/	l1; l2; ...; ln
/	ld

1:
	mov	*(sp)+,r1
	sub	(r1)+,r0	/ low limit
	cmp	r0,(r1)+	/ n cases
	blo	1f
	mov	-(r1),r0	/ default
1:
	asl	r0
	add	r0,r1
	jmp	*(r1)+

binary:
	jsr	pc,*$1f

/	end
/	v1;l1; v2;l2; ...; vn;ln
/end:	ld

1:
	mov	*(sp)+,r1	/ low
	mov	(r1)+,r2	/ high
	mov	(r2),-(sp)	/ default
	br	1f

llo:
	mov	r3,r2
	br	1f
lhi:
	mov	r3,r1
	add	$4,r1
1:
	mov	r2,r3
	sub	r1,r3
	beq	1f
	asr	r3
	bic	$3,r3
	add	r1,r3
	cmp	r0,(r3)
	bhi	lhi
	blo	llo
	tst	(sp)+
	jmp	*2(r3)
1:
	rts	pc

.bss
base:	.=.+2
twon:	.=.+2
twona:	.=.+2
_fin:	.=.+518.
_fout:	.=.+518.

chdir.sD¡än
“/ C library -- chdir

/ error = chdir(string);

	.globl	_chdir

.data
_chdir:
	1f
.text
1:
	mov	2(sp),0f
	clr	r0
	sys	chdir; 0:..
	adc	r0
	rts	pc

chmod.sD¡l
­/ C library -- chmod

/ error = chmod(string, mode);

	.globl	_chmod

.data
_chmod:
	1f
.text
1:
	mov	2(sp),0f
	mov	4(sp),0f+2
	clr	r0
	sys	chmod; 0:..; ..
	adc	r0
	rts	pc

chown.sD¡m
®/ C library -- chown

/ error = chown(string, owner);

	.globl	_chown

.data
_chown:
	1f
.text
1:
	mov	2(sp),0f
	mov	4(sp),0f+2
	clr	r0
	sys	chown; 0:..; ..
	adc	r0
	rts	pc

close.sD¡b–
–/ C library -- close

/error =  close(file);

	.globl	_close

.data
_close:
	1f
.text
1:
	mov	2(sp),r0
	clr	r1
	sys	close
	adc	r1
	mov	r1,r0
	rts	pc

creat.sD¡[¨
Ë/ C library -- creat

/ file = creat(string, mode);
/
/ file == -1 if error

	.globl	_creat

.data
_creat:
	1f
.text
1:
	mov	2(sp),0f
	mov	4(sp),0f+2
	sys	creat; 0:..; ..
	bec	1f
	mov	$-1,r0
1:
	rts	pc

crt0.sI¡¡Š
Ä/ C runtime startoff

.globl	retrn

.globl	_main

start:
	mov	$mq,r4
	mov	sp,r0
	mov	(r0),-(sp)
	tst	(r0)+
	mov	r0,2(sp)
	jsr	pc,*_main
	clr	r0
	sys	exit

retrn:
	mov	r5,sp
	mov	(sp)+,r5
	rts	pc

ctime.sD¡‡Ç
</ C library -- ctime

/ ctime(v1, v2);
/ v1 is input time [2]
/ v2 is char[16] ascii time
/ format is 0123456789012345
/           Mmm dd hh:mm:sse
/

.globl	_ctime
.globl	ctime

.data
_ctime:
	1f
.text
1:
	mov	2(sp),r0
	mov	(r0)+,-(sp)
	mov	(r0)+,mq
	mov	(sp)+,ac
	mov	4(sp),r0
	clrb	15.(r0)
	jsr	pc,ctime
	rts	pc

execl.sD¡«á
·/ C library -- execl

/ execl(file, arg1, arg2, ... , 0);
/
/
	.globl	_execl

.data
_execl:
	1f
.text
1:
	mov	2(sp),0f
	mov	sp,r0
	add	$4,r0
	mov	r0,0f+2
	sys	exec; 0:..; ..
	rts	pc

execv.sE¡
å/ C library -- execv

/ execv(file, argv);
/
/ where argv is a vector argv[0] ... argv[x], 0
/ last vector element must be 0
/
	.globl	_execv

.data
_execv:
	1f
.text
1:
	mov	2(sp),0f
	mov	4(sp),0f+2
	sys	exec; 0:..; ..
	rts	pc

exit.sE¡‹U
…/ C library -- exit

/ exit(code)
/ code is return in r0 to system

.globl	_exit

.data
_exit:
	1f
.text
1:
	mov	2(sp),r0
	sys	exit

fork.sE¡Ýa
Ø/ C library -- fork

/ pid = fork();
/
/ pid == 0 in child process; pid == -1 means error return

	.globl	_fork

.data
_fork:
	1f
.text
1:
	sys	fork
		br 1f
	bes	2f
	rts	pc
2:
	mov	$-1,r0
	rts	pc
1:
	clr	r0
	rts	pc

fstat.sE¡
…
ø/ C library -- fstat

/ error = fstat(file, statbuf);

/ int statbuf[17] or
/ char statbuf[34]
/ as appropriate

	.globl	_fstat

.data
_fstat:
	1f
.text
1:
	mov	2(sp),r0
	mov	4(sp),0f
	sys	fstat; 0:..
	bec	1f
	mov	$1,r0
	rts	pc
1:
	clr	r0
	rts	pc

getchr.sH¡0å
»/ C library -- getchar

.globl	_getchar
.globl	_fin

.globl	getc

.data
_getchar:
	1f
.text
1:
	jsr	r5,getc; _fin
	bcs	1f
	tst	r0
	beq	1b
	rts	pc
1:
	clr	r0
	rts	pc

.bss
_fin:	.=.+518.

getuid.sE¡Õ›
°/ C library -- getuid

/ uid = getuid();
/
/ uid == -1 if error

	.globl	_getuid

.data
_getuid:
	1f
.text
1:
	sys	getuid
	bec	1f
	mov	$-1,r0
	rts	pc
1:
	bic	$!377,r0
	rts	pc

gtty.ssE¡F³
/ C library -- gtty

/ error = gtty(filep, ttyvec);

/ filep is descriptor of open tty
/ ttyvec[0, 1, 2] correspond to args of gtty

.globl	_gtty

.data
_gtty:
	1f
.text
1:
	mov	2(sp),r0
	mov	4(sp),0f
	sys	gtty; 0:..
	bes	1f
	clr	r0
	rts	pc
1:
	mov	$1,r0
	rts	r0

intr.ssF¡Åh
Š/ C library -- intr

/ intr(0); /* exit on interrupt */
/ intr(anything_odd); /* ignore interrupts */
/ intr(label); /* goto label on interrupts */

	.globl	_intr

.data
_intr:
	1f
.text
1:
	mov	2(sp),r0
	beq	1f
	bit	$1,r0
	beq	2f
1:
	bic	$1,r0
	mov	r0,0f
	sys	intr; 0:..
	rts	pc
2:
	mov	r5,9f
	mov	r0,9f+2
	sys	intr; 1f
	rts	pc

/ here on interrupts

1:
	mov	9f,r5
	jmp	*9f+2

.bss
9:
	.=.+4

link.ssF¡fw
°/ C library -- link

/ error = link(old-file, new-file);
/

	.globl	_link

.data
_link:
	1f
.text
1:
	mov	2(sp),0f
	mov	4(sp),0f+2
	clr	r0
	sys	link; 0:..; ..
	adc	r0
	rts	pc

makdir.sF¡$€
˜/ C library -- makdir

/ error = makdir(string);

	.globl	_makdir

.data
_makdir:
	1f
.text
1:
	mov	2(sp),0f
	clr	r0
	sys	makdir; 0:..
	adc	r0
	rts	pc

open.ssF¡’Š
È/ C library -- open

/ file = open(string, mode)
/
/ file == -1 means error

	.globl	_open

.data
_open:
	1f
.text
1:
	mov	2(sp),0f
	mov	4(sp),0f+2
	sys	open; 0:..; ..
	bec	1f
	mov	$-1,r0
1:
	rts	pc

printf.s„¡6
q.globl	_printn
.data; _printn:1f
.text; 1:mov r5,-(sp); mov sp,r5
tst	-(sp)
mov	4(r5),(r4)
mov	6(r5),div
mov	(r4),r0
mov	r0,-2(r5)
bne	l2
jmp	l1
l2:mov	6(r5),-(sp)
mov	-2(r5),-(sp)
jsr	pc,*_printn
cmp	(sp)+,(sp)+
l1:mov	4(r5),(r4)
mov	6(r5),div
mov	ac,r0
mov	r0,-(sp)
add	$60,(sp)
jsr	pc,*_putchar
tst	(sp)+
jmp	retrn
.globl	_printf
.data; _printf:1f
.text; 1:mov r5,-(sp); mov sp,r5
add	$-10,sp
mov	r5,r0
add	$6,r0
mov	r0,-4(r5)
.data; l3: 1f; .text; 1:
l4:mov	4(r5),r0
inc	4(r5)
movb	(r0),r0
mov	r0,-10(r5)
cmp	r0,$45
bne	l6
jmp	l5
l6:tst	-10(r5)
beq	l8
jmp	l7
l8:jmp	retrn
l7:mov	-10(r5),-(sp)
jsr	pc,*_putchar
tst	(sp)+
jmp	l4
l5: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,bswitch; l9
l10:l11:tst	-6(r5)
blt	l13
jmp	l12
l13:mov	-6(r5),r0
neg	r0
mov	r0,-6(r5)
tst	-6(r5)
blt	l15
jmp	l14
l15:cmp	-10(r5),$157
beq	l17
jmp	l16
l17:.data; l18:
.byte 61,60,60,60,60,60,0
.even;.text
mov	$l18,-(sp)
jsr	pc,*_printf
tst	(sp)+
jmp	l19
l16:.data; l20:
.byte 55,63,62,67,66,70,0
.even;.text
mov	$l20,-(sp)
jsr	pc,*_printf
tst	(sp)+
l19:jmp	*l3
l14:mov	$55,-(sp)
jsr	pc,*_putchar
tst	(sp)+
l12:cmp	-10(r5),$157
bne	l21
mov	$10,-(sp)
br	l22
l21:mov	$12,-(sp)
l22:mov	-6(r5),-(sp)
jsr	pc,*_printn
cmp	(sp)+,(sp)+
jmp	*l3
l23:mov	-6(r5),-(sp)
jsr	pc,*_putchar
tst	(sp)+
jmp	*l3
l24:mov	-6(r5),-2(r5)
l25:mov	-2(r5),r0
inc	-2(r5)
movb	(r0),r0
mov	r0,-10(r5)
bne	l27
jmp	l26
l27:mov	-10(r5),-(sp)
jsr	pc,*_putchar
tst	(sp)+
jmp	l25
l26:jmp	*l3
l28:.data
l9:163; l24
143; l23
157; l11
144; l10
l28; 0
.text
mov	$45,-(sp)
jsr	pc,*_putchar
tst	(sp)+
dec	4(r5)
mov	-4(r5),r0
sub	$2,-4(r5)
jmp	*l3
jmp	retrn
putchr.s…¡Y€
½/ C library -- putchar

/ char = putchar(char)

/ buffer output if fout is not 1

.globl	_putchar
.globl	_fout
.globl	_flush

.globl	putc
.globl	flush

.data
_putchar:
	1f
.text
1:
	mov	2(sp),r0
	tst	_fout
	bne	1f
	mov	$1,_fout
1:
	jsr	r5,putc; _fout
	movb	3(sp),r0
	beq	1f
	jsr	r5,putc; _fout
1:
	cmp	_fout,$1
	bne	1f
	jsr	r5,flush; _fout
1:
	mov	2(sp),r0
	rts	pc

.data
_flush:
	1f
.text
1:
	jsr	r5,flush; _fout
	rts	pc

.bss
_fout:	.=.+518.

read.ssF¡W–
õ/ C library -- read

/ nread = read(file, buffer, count);
/
/ nread ==0 means eof; nread == -1 means error

	.globl	_read

.data
_read:
	1f
.text
1:
	mov	2(sp),r0
	mov	4(sp),0f
	mov	6(sp),0f+2
	sys	read; 0:..; ..
	bec	1f
	mov	$-1,r0
1:
	rts	pc

seek.ssF¡º¨
Ò/ C library -- seek

/ error = seek(file, offset, ptr);

	.globl	_seek

.data
_seek:
	1f
.text
1:
	mov	2(sp),r0
	mov	4(sp),0f
	mov	6(sp),0f+2
	sys	seek; 0:..; ..
	bec	1f
	mov	$1,r0
	rts	r0
1:
	clr	r0
	rts	pc


setuid.sF¡œ±
¥/ C library -- setuid

/ error = setuid(uid);

	.globl	_setuid

.data
_setuid:
	1f
.text
1:
	mov	2(sp),r0
	sys	setuid
	bec	1f
	mov	$1,r0
	rts	pc
1:
	clr	r0
	rts	pc

stat.ssF¡¦Â
û/ C library -- stat

/ error = stat(string, statbuf);

/ int statbuf[17] or
/ char statbuf[34]
/ as appropriate

	.globl	_stat

.data
_stat:
	1f
.text
1:
	mov	2(sp),0f
	mov	4(sp),0f+2
	sys	stat; 0:..; ..
	bec	1f
	mov	$1,r0
	rts	pc
1:
	clr	r0
	rts	pc

stty.ssF¡LÐ
/ C library -- stty

/ error = stty(filep, ttyvec);

/ filep is descriptor of open tty
/ ttyvec[0, 1, 2] correspond to args of stty

.globl	_stty

.data
_stty:
	1f
.text
1:
	mov	2(sp),r0
	mov	4(sp),0f
	sys	stty; 0:..
	bes	1f
	clr	r0
	rts	pc
1:
	mov	$1,r0
	rts	pc

switch.sI¡66
¢/ C library -- switch

.globl	bswitch

bswitch:
	mov	*(sp)+,r1
1:
	cmp	(r1)+,r0
	beq	1f
	tst	(r1)+
	bne	1b
2:
	mov	-4(r1),pc
1:
	mov	(r1)+,r0
	beq	2b
	mov	r0,pc

time.ssF¡Þ
¶/ C library -- time

/ tvec = time(tvec);
/
/ tvec[0], tvec[1] contain the time

	.globl	_time

.data
_time:
	1f
.text
1:
	mov	2(sp),r0
	sys	time
	mov	ac,(r0)
	mov	mq,2(r0)
	rts	pc

unlink.sF¡1å
š/ C library -- unlink

/ error = unlink(string);
/

	.globl	_unlink

.data
_unlink:
	1f
.text
1:
	mov	2(sp),0f
	clr	r0
	sys	unlink; 0:..
	adc	r0
	rts	pc

wait.ssG¡XP
]/ C library -- wait

/ pid = wait();
/   or,
/ pid = wait(&status);
/
/ pid == -1 if error
/ status idicates fate of process, if given

	.globl	_wait

.data
_wait:
	1f
.text
1:
	clr	mq
	sys	wait
	bec	1f
	mov	$-1,r0
	rts	pc
1:
	cmp	*(sp),tstins	/ arg count
	bne	1f
	mov	mq,*2(sp)	/ status return
1:
	rts	pc

tstins:	tst	(sp)+		/ stack pop for 1 arg

write.sG¡P\
ë/ C library -- write

/ nwritten = write(file, buffer, count);
/
/ nwritten == -1 means error

	.globl	_write

.data
_write:
	1f
.text
1:
	mov	2(sp),r0
	mov	4(sp),0f
	mov	6(sp),0f+2
	sys	write; 0:..; ..
	bec	1f
	mov	$-1,r0
1:
	rts	pc

printf.cH¡¦H
Pprintn(n,b) {
	extern putchar;
	auto a;

	if(a=n/b) /* assignment, not test for equality */
		printn(a, b); /* recursive */
	putchar(n%b + '0');
}

printf(fmt,x1,x2,x3,x4,x5,x6,x7,x8,x9)
	char fmt[];
	{
	extern printn, putchar;
	char s[];
	auto adx[], x, c;

	adx = &x1; /* argument pointer */
loop:
	while((c = *fmt++) != '%') {
		if(c == '\0')
			return;
		putchar(c);
	}
	x = *adx++;
	switch (c = *fmt++) {

	case 'd': /* decimal */
	case 'o': /* octal */
		if(x < 0) {
			x = -x;
			if(x<0) {  	/* is - infinity */
				if(c=='o')
					printf("100000");
				else
					printf("-32768");
				goto loop;
			}
			putchar('-');
		}
		printn(x, c=='o'?8:10);
		goto loop;

	case 'c': /* char */
		putchar(x);
		goto loop;

	case 's': /* string */
		s = x;
		while(c = *s++)
			putchar(c);
		goto loop;
	}
	putchar('%');
	fmt--;
	adx--;
	goto loop;
}