V1/u5.s

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

/ u5 -- unix

mget:
	mov	*u.fofp,mq / file offset in mq
	clr	ac / later to be high sig
	mov	$-8,lsh   / divide ac/mq by 256.
	mov	mq,r2
	bit	$10000,i.flgs / lg/sm is this a large or small file
	bne	4f / branch for large file
	bit	$!17,r2
	bne	3f / branch if r2 greater than or equal to 16
	bic	$!16,r2 / clear all bits but bits 1,2,3
	mov	i.dskp(r2),r1 / r1 has physical block number
	bne	2f / if physical block num is zero then need a new block
		   / for file
	jsr	r0,alloc / allocate a new block
	mov	r1,i.dskp(r2) / physical block number stored in i-node
	jsr	r0,setimod / set inode modified byte (imod)
	jsr	r0,clear / zero out disk/drum block just allocated
2:
	rts	r0
3: / adding on block which changes small file to a large file
	jsr	r0,alloc / allocate a new block for this file; block number
	                 /in r1
	jsr	r0,wslot / set up I/O buffer for write, r5 points to first
			 / data word in buffer
	mov	$8.,r3 / next 6 instructions transfer old physical block
		       / pointers
	mov	$i.dskp,r2 / into new indirect block for the new large file
1:
	mov	(r2),(r5)+
	clr	(r2)+
	dec	r3
	bgt	1b
	mov	$256.-8.,r3 / clear rest of data buffer
1:
	clr	(r5)+
	dec 	r3
	bgt	1b
	jsr	r0,dskwr / write new indirect block on disk
	mov	r1,i.dskp / put pointer to indirect block in i-node
	bis	$10000,i.flgs / set large file bit in i.flgs word of i-node
	jsr	r0,setimod / set i-node modified flag
	br	mget
4: / large file
	mov	$-8,lsh / divide byte number by 256.
	bic	$!776,r2 / zero all bits but 1,2,3,4,5,6,7,8; gives offset
			 / in indirect block
	mov	r2,-(sp) / save on stack
	mov	mq,r2 / calculate offset in i-node for pointer to proper
       		      / indirect block
	bic	$!16,r2
	mov	i.dskp(r2),r1
	bne	2f / if no indirect block exists
	jsr	r0,alloc / allocate a new block
	mov	r1,i.dskp(r2) / put block number of new block in i-node
	jsr	r0,setimod / set i-node modified byte
	jsr	r0,clear / clear new block
2:
	jsr	r0,dskrd / read in indirect block
	mov	(sp)+,r2 / get offset
	mov	r1,-(sp) / save block number of indirect block on stack
	add	r5,r2 / r5 points to first word in indirect block, r2
	              / points to location of inter
	mov	(r2),r1 / put physical block no of block in file
	                / sought in r1
	bne	2f / if no block exists
	jsr	r0,alloc / allocate a new block
	mov	r1,(r2) / put new block number into proper location in
	                / indirect block
	mov	(sp)+,r1 / get block number of indirect block
	mov	(r2),-(sp) / save block number of new block
	jsr	r0,wslot
	jsr	r0,dskwr / write newly modified indirect block back out
	                 / on disk
	mov	(sp),r1 / restore block number of new block
	jsr	r0,clear / clear new block
2:
	tst	(sp)+ / bump stack pointer
	rts	r0

alloc:
	mov	r2,-(sp) / save r2, r3 on stack
	mov	r3,-(sp)
	mov	$systm,r2 / start of inode and free storage map for drum
	tst	cdev
	beq	1f / drum is device
	mov	$mount,r2 / disk or tape is device, start of inode and free
	                  / storage map
1:
	mov	(r2)+,r1 / first word contains number of bytes in free
			 / storage map
	asl	r1 / multiply r1 by eight gives, number of blocks in device
	asl	r1
	asl	r1
	mov	r1,-(sp) / save # of blocks in device on stack
	clr	r1 / r1 contains bit count of free storage map
1:
	mov	(r2)+,r3 / word of free storage map in r3
	bne	1f / branch if any free blocks in this word
	add	$16.,r1
	cmp	r1 ,(sp) / have we examined all free storage bytes
	blo	1b
	jmp	panic / found no free storage
1:
	asr	r3 / find a free block
	bcs	1f / branch when free block found; bit for block k is in
		   / byte k/8 / in bit k (mod 8)
	inc	r1 / increment bit count in bit k (mod8)
	br	1b
1:
	tst	(sp)+ / bump sp
	jsr	r0,3f / have found a free block
	bic	r3,(r2) / set bit for this block i.e. assign block
	br	2f

free:
	mov	r2,-(sp) / save r2, r3
	mov	r3,-(sp)
	jsr	r0,3f / set up bit mask and word no. in free storage map
		      / for block
	bis	r3,(r2) / set free storage block bit; indicates free block
2:
	mov	(sp)+,r3 / restore r2, r3
	mov	(sp)+,r2
	tst	cdev / cdev = 0, block structured, drum; cdev = 1
		     / mountable device
	bne	1f
	incb	smod / set super block modified for drum
	rts	r0
1:
	incb	mmod / set super block modified for mountable device
	rts	r0
3:
	mov	r1,r2 / block number, k, = 1
	bic	$!7,r2 / clear all bits but 0,1,2; r2 = (k) mod (8)
	clr	r3
	bisb	2f(r2),r3 / use mask to set bit in r3 corresponding to
			  / (k) mod 8
	mov	r1,r2 / divide block number by 16
	asr	r2
	asr	r2
	asr	r2
	asr	r2
	bcc	1f / branch if bit 3 in r1 was 0 i.e., bit for block is in
		   / lower half of word
	swab	r3 / swap bytes in r3; bit in upper half of word in free
		   / storage map
1:
	asl	r2 / multiply block number by 2; r2 = k/8
	add	$systm+2,r2 / address of word of free storage map for drum
	    		    / with block bit in it
	tst	cdev
	beq	1f / cdev = 0 indicates device is drum
	add	$mount-systm,r2 / address of word of free storage map for
				/ mountable device with bit of block to be
				/ freed
1:
	rts	r0 / return to 'free'
2:
	.byte	1,2,4,10,20,40,100,200 / masks for bits 0,...,7

access:
	jsr	r0,iget / read in i-node for current directory (i-number
			/ passed in r1)
	mov	i.flgs,r2
	cmpb	i.uid,u.uid / is user same as owner of file
	bne	1f / no, then branch
	asrb	r2 / shift owner read write bits into non owner
		   / read/write bits
	asrb	r2
1:
	bit	r2,(r0)+ / test read-write flags against argument in
			 / access call
	bne	1f
	tstb	u.uid
	beq	1f
	jmp	error
1:
	rts	r0

setimod:
	movb	$1,imod / set current i-node modified bytes
	mov	s.time,i.mtim / put present time into file modified time
	mov	s.time+2,i.mtim+2
	rts	r0

imap: / get the byte that has the allocation bit for the i-number contained
      / in r1
	mov	$1,mq / put 1 in the mq
	mov	r1,r2 / r2 now has i-number whose byte in the map we
 		      / must find
	sub	$41.,r2 / r2 has i-41
	mov	r2,r3 / r3 has i-41
	bic	$!7,r3 / r3 has (i-41) mod 8 to get the bit position
	mov	r3,lsh / move the 1 over (i-41) mod 8 positions to the left
		       / to mask the correct bit
	asr	r2
	asr	r2
	asr	r2 / r2 has (i-41) base 8 of the byte no. from the start of
		   / the map
	mov	r2,-(sp) / put (i-41) base 8 on the stack
	mov	$systm,r2 / r2 points to the in-core image of the super
			  / block for drum
	tst	cdev / is the device the disk
	beq	1f / yes
	add	$mount-systm,r2 / for mounted device, r2 points to 1st word
				/ of its super block
1:
	add	(r2)+,(sp) / get byte address of allocation bit
	add	(sp)+,r2 / ?
	add	$2,r2 / ?
	rts	r0

iget:
	cmp	r1,ii / r1 = i-number of current flle
	bne	1f
	cmp	idev,cdev / is device number of i-node = current device
	beq	2f
1:
	tstb	imod / has i-node of current file been modified i.e.,
	       	     / imod set
	beq	1f
	clrb	imod / if it has, we must write the new i-node out on disk
	mov	r1,-(sp)
	mov	cdev,-(sp)
	mov	ii,r1
	mov	idev,cdev
	jsr	r0,icalc; 1
	mov	(sp)+,cdev
	mov	(sp)+,r1
1:
	tst	r1 / is new i-number non zero
	beq	2f / branch if r1=0
	tst	cdev / is the current device number non zero (i.e., device
	       	     / =/ drum)
	bne	1f / branch 1f cdev =/ 0
	cmp	r1,mnti / mnti is the i-number of the cross devlce
			 / file (root directory of mounted devlce)
	bne	1f
	mov	mntd,cdev / make mounted device the current device
	mov	rootdir,r1
1:
	mov	r1,ii
	mov	cdev,idev
	jsr	r0,icalc; 0 / read in i-node ii
2:
	mov	ii,r1
	rts	r0

icalc: / i-node i is located in block (i+31.)/16. and begins 32.*
       / (i+31)mod16 bytes from its start
	add	$31.,r1 / add 31. to i-number
	mov	r1,-(sp) / save i+31. on stack
	asr	r1 / divide by 16.
	asr	r1
	asr	r1
	asr	r1 / r1 contains block number of block in which
		   / i-node exists
	jsr	r0,dskrd / read in block containing i-node i.
	tst	(r0)
	beq	1f / branch to wslot when argument in icalc call = 1
	jsr	r0,wslot / set up data buffer for write (will be same buffer
			 / as dskrd got)
1:
	bic	$!17,(sp) / zero all but last 4 bits; gives (i+31.) mod 16
	mov	(sp)+,mq / calculate offset in data buffer; 32.*(i+31.)mod16
	mov	$5,lsh / for i-node i.
	add	mq,r5 / r5 points to first word in i-node i.
	mov	$inode,r1 / inode is address of first word of current i-node
	mov	$16.,r3
	tst	(r0)+ / branch to 2 fwhen argument in icalc call = 0
	beq	2f / r0 now contains proper return address for rts r0
1:
	mov	(r1)+,(r5)+ / over write old i-node
	dec	r3
	bgt	1b
	jsr	r0,dskwr / write inode out on device
	rts	r0
2:
	mov	(r5)+,(r1)+ / read new i-node into "inode" area of core
	dec	r3
	bgt	2b
	rts	r0

itrunc:
	jsr	r0,iget
	mov	$i.dskp,r2 / address of block pointers in r2
1:
	mov	(r2)+,r1 / move physical block number into r1
	beq	5f
	mov	r2,-(sp)
	bit	$10000,i.flgs / test large file bit?
	beq	4f / if clear, branch
	mov	r1,-(sp) / save block number of indirect block
	jsr	r0,dskrd / read in block, 1st data word pointed to by r5
	mov	$256.,r3 / move word count into r3
2:
	mov	(r5)+,r1 / put 1st data word in r1; physical block number
	beq	3f / branch if zero
	mov	r3,-(sp) / save r3, r5 on stack
	mov	r5,-(sp)
	jsr	r0,free / free block in free storage map
	mov	(sp)+,r5
	mov	(sp)+,r3
3:
	dec	r3 / decrement word count
	bgt	2b / branch if positive
	mov	(sp)+,r1 / put physical block number of indirect block
4:
	jsr	r0,free / free indirect block
	mov	(sp)+,r2
5:
	cmp	r2,$i.dskp+16.
	bne	1b / branch until all i.dskp entries check
	bic	$10000,i.flgs / clear large file bit
	clr	i.size / zero file size
	jsr	r0,copyz; i.dskp; i.dskp+16. / zero block pointers
	jsr	r0,setimod / set i-node modified flag
	mov	ii,r1
	rts	r0