V1/u6.s

Compare this file to the similar file:
Show the results in this format:

/ u6 -- unix

readi:
	clr	u.nread / accumulates number of bytes transmitted
	tst	u.count / is number of bytes to be read greater than 0
	bgt	1f / yes, branch
	rts	r0 / no, nothing to read; return to caller
1:
	mov	r1,-(sp) / save i-number on stack
	cmp	r1,$40. / want to read a special file (i-nodes 1,...,40 are
		    / for special files)
	ble	1f / yes, branch
	jmp	dskr / no, jmp to dskr; read file with i-node number (r1)
		     / starting at byte ((u.fofp)), read in u.count bytes
1:
	asl	r1 / multiply inode number by 2
	jmp	*1f-2(r1)
1:
	rtty / tty; r1=2
	rppt / ppt; r1=4
	rmem / mem; r1=6
	rrf0 / rf0
	rrk0 / rk0
	rtap / tap0
	rtap / tap1
	rtap / tap2
	rtap / tap3
	rtap / tap4
	rtap / tap5
	rtap / tap6
	rtap / tap7
	rcvt / tty0
	rcvt / tty1
	rcvt / tty2
	rcvt / tty3
	rcvt / tty4
	rcvt / tty5
	rcvt / tty6
	rcvt / tty7
	rcrd/ crd

rtty: / read from console tty
	mov	tty+[8*ntty]-8+6,r5 / r5 is the address of the 4th word of
				    / of the control and status block
	tst	2(r5) / for the console tty; this word points to the console
		      / tty buffer
	bne	1f / 2nd word of console tty buffer contains number
	           / of chars. Is this number non-zero?
	jsr	r0,canon; ttych / if 0, call 'canon' to get a line
			    / (120 chars.)
1:
	tst	2(r5) / is the number of characters zero
	beq	ret1 / yes, return to caller via 'ret1'
	movb	*4(r5),r1 / no, put character in r1
	inc	4(r5) / 3rd word of console tty buffer points to byte which
		      / contains the next char.
	dec	2(r5) / decrement the character count
	jsr	r0,passc / move the character to core (user)
	br	1b / get next character

ret1:
	jmp	ret / return to caller via 'ret'

rppt: / read paper tape
	jsr	r0,pptic / gets next character in clist for ppt input and
			 / places
		br ret / it in r1; if there 1s no problem with reader, it
		       / also enables read bit in prs
	jsr	r0,passc / place character in users buffer area
	br	rppt

rmem: / transfer characters from memory to a user area of core
	mov	*u.fofp,r1 / save file offset which points to the char to
		           / be transferred to user
	inc	*u.fofp / increment file offset to point to 'next' char in
		        / memory file
	movb	(r1),r1 / get character from memory file, put it in r1
	jsr	r0,passc / move this character to the next byte of the
		         / users core area
	br	 rmem / continue
1:
rcrd:
	jmp	error / see 'error' routine

dskr:
	mov	(sp),r1 / i-number in r1
	jsr	r0,iget / get i-node (r1) into i-node section of core
	mov	i.size,r2 / file size in bytes in r2
	sub	*u.fofp,r2 / subtract file offset
	blos	ret
	cmp	r2,u.count / are enough bytes left in file to carry out read
	bhis	1f
	mov	r2,u.count / no, just read to end of file
1 :
	jsr	r0,mget / returns physical block number of block in file
		        / where offset points
	jsr	r0,dskrd / read in block, r5 points to 1st word of data in
		         / buffer
	jsr	r0,sioreg
2:
	movb	(r2)+,(r1)+ / move data from buffer into working core
		            / starting at u.base
	dec	r3
	bne	2b / branch until proper number of bytes are transferred
	tst	u.count / all bytes read off disk
	bne	dskr
	br	ret

passc:
	movb	r1,*u.base / move a character to the next byte of the
		           / users buffer
	inc	u.base / increment the pointer to point to the next byte
		       / in users buffer
	inc	u.nread / increment the number of bytes read
	dec	u.count / decrement the number of bytes to be read
	bne	1f / any more bytes to read?; yes, branch
	mov	(sp)+,r0 / no, do a non-local return to the caller of
		         / 'readi' by:
ret: / (1) pop the return address off the stack into r0
	mov	(sp)+,r1 / (2) pop the i-number off the stack into r1
1:
	clr	*$ps / clear processor status
	rts	r0 / return to address currently on top of stack

writei:
	clr	u.nread / clear the number of bytes transmitted during
		        / read or write calls
	tst	u.count / test the byte count specified by the user
	bgt	1f / any bytes to output; yes, branch
	rts	r0 / no, return - no writing to do
1:
	mov	r1 ,-(sp) / save the i-node number on the stack
	cmp	r1,$40. / does the i-node number indicate a special file?
	bgt	dskw / no, branch to standard file output
	asl	r1 / yes, calculate the index into the special file
	jmp	*1f-2(r1) / jump table and jump to the appropriate routine
1:
	wtty	/ tty
	wppt	/ ppt
	wmem	/ mem
	wrf0	/ rf0
	wrk0	/ rk0
	wtap	/ tap0
	wtap	/ tap1
	wtap	/ tap2
	wtap	/ tap3
	wtap	/ tap4
	wtap	/ tap5
	wtap	/ tap6
	wtap	/ tap7
	xmtt	/ tty0
	xmtt	/ tty1
	xmtt	/ tty2
	xmtt	/ tty3
	xmtt	/ tty4
	xmtt	/ tty5
	xmtt	/ tty6
	xmtt	/ tty7
/	w1pr / lpr

wtty:
	jsr	r0,cpass / get next character from user buffer area; if
		         / none go to return address in syswrite
	tst	r1 / is character = null
	beq	wtty / yes, get next character
1 :
	mov	$240,*$ps / no, set processor priority to five
	cmpb	cc+1,$20. / is character count for console tty greater
		          / than 20
	bhis	2f / yes; branch to put process to sleep
	jsr	r0,putc; 1 / find place in freelist to assign to console
		           / tty and
		br 2f / place character in list; if none available
		      / branch to put process to sleep
	jsr	r0,startty / attempt to output character on tty
	br	wtty
2:
	mov	r1,-(sp) / place character on stack
	jsr	r0,sleep; 1 / put process to sleep
	mov	(sp)+,r1 / remove character from stack
	br	1b / try again to place character in clist and output

wppt:
	jsr	r0,cpass / get next character from user buffer area,
		         / if none return to writei's calling routine
	jsr	r0,pptoc / output character on ppt
	br	wppt
/wlpr:
/	jsr	r0,cpass
/	cmp	r0,$'a
/	blo	1f
/	cmp	r1,$'z
/	bhi	1f
/	sub	$40,r1
/1:
/	jsr	r0,lptoc
/	br	wlpr

wmem: / transfer characters from a user area of core to memory file
	jsr	r0,cpass / get next character from users area of core and
		         / put it in r1
	mov	r1,-(sp) / put character on the stack
	mov	*u.fofp,r1 / save file offset in r1
	inc	*u.fofp / increment file offset to point to next available
		        / location in file
	movb	(sp)+,(r1) / pop char off stack, put in memory loc assigned
		           / to it
	br	wmem / continue
1:
	jmp	error / ?

dskw: / write routine for non-special files
	mov	(sp),r1 / get an i-node number from the stack into r1
	jsr	r0,iget / write i-node out (if modified), read i-node 'r1'
		        / into i-node area of core
	mov	 *u.fofp,r2 / put the file offset [(u.off) or the offset in
		            / the fsp entry for this file] in r2
	add	 u.count,r2 / no. of bytes to be written + file offset is
		            / put in r2
	cmp	 r2,i.size / is this greater than the present size of
		           / the file?
	blos	 1f / no, branch
	 mov	r2,i.size / yes, increase the f11e size to file offset +
		           / no. of data bytes
	 jsr	r0,setimod / set imod=1 (i.e., core inode has been
		           / modified), stuff tlme of modification into
		           / core image of i-node
1:
	jsr	r0,mget / get the block no. in which to write the next data
		        / byte
	bit	*u.fofp,$777 / test the lower 9 bits of the file offset
	bne	2f / if its non-zero, branch; if zero, file offset = 0,
		   / 512, 1024,...(i.e., start of new block)
	cmp	u.count,$512. / if zero, is there enough data to fill an
		              / entire block? (i.e., no. of
	bhis	3f / bytes to be written greater than 512.? Yes, branch.
		   / Don't have to read block
2: / in as no past info. is to be saved (the entire block will be
   / overwritten).
	jsr	r0,dskrd / no, must retain old info.. Hence, read block 'r1'
		         / into an I/O buffer
3:
	jsr	r0,wslot / set write and inhibit bits in I/O queue, proc.
		         / status=0, r5 points to 1st word of data
	jsr	r0,sioreg / r3 = no. of bytes of data, r1 = address of data,
		          / r2 points to location in buffer in which to
		          / start writing data
2:
	movb	(r1 )+,(r2)+ / transfer a byte of data to the I/O buffer
	dec	r3 / decrement no. of bytes to be written
	bne	2b / have all bytes been transferred? No, branch
	jsr	r0,dskwr / yes, write the block and the i-node
	tst	u.count / any more data to write?
	bne	1b / yes, branch
	jmp	ret / no, return to the caller via 'ret'

cpass: / get next character from user area of core and put it in r1
	tst	u.count / have all the characters been transferred (i.e.,
		        / u.count, # of chars. left
	beq	1f / to be transferred = 0?) yes, branch
	dec	u.count / no, decrement u.count
	movb	*u.base,r1 / take the character pointed to by u.base and
		           / put it in r1
	inc	u.nread / increment no. of bytes transferred
	inc	u.base / increment the buffer address to point to the
	rts	r0 / next byte
1: 
	mov	(sp)+,r0 / put return address of calling routine into r0
	mov	(sp)+,r1 / i-number in r1
	rts	r0 / non-local return

sioreg:
	mov	*u.fofp,r2 / file offset (in bytes) is moved to r2
	mov	r2,r3 / and also to r3
	bis	$177000,r3 / set bits 9,...,15. of file offset in r3
	bic	$!777,r2 / calculate file offset mod 512.
	add	r5,r2 / r2 now points to 1st byte in system buffer where
		      / data is to be placed
	mov	u.base,r1 / address of data is in r1
	neg	r3 / 512 - file offset (mod512.) in r3 (i.e., the number
		   / of free bytes in the file block
	cmp	r3,u.count / compare this with the number of data bytes to
		           / be written to the file
	blos	2f / if less than branch. Use the number of free bytes
		   / in the file block as the number to be written
	mov	u.count,r3 / if greater than, use the number of data bytes
		           / as the number to be written
2:
	add	r3,u.nread / r3 + number of bytes xmitted during write is
		           / put into u.nread
	sub	r3,u.count / u.count = no. of bytes that still must be
		           / written or read
	add	r3,u.base /  u.base points to the 1st of the remaining data
		          / bytes
	add	r3,*u.fofp / new file offset = number of bytes done + old
		           / file offset
	rts	r0