V1/u8.s

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

/ u8 -- unix

rtap: / read from the dec tape
	asr	r1 / divide the i-number by 2
	sub	$4.,r1 / (i-number/2)-4  r1
	mov	r1,cdev / cdev now has device number
	jsr	r0,bread; 578. / read in block thats in *u.fofp

wtap:
	asr	r1 / divide i-number by 2
	sub	$4.,r1 / r1 = i-number minus 4
	mov	r1,cdev / this is used as the device number
	jsr	r0,bwrite; 578. / write block (u.fofp) on dec tape
				/ Maximum

rrk0:
	mov	$1,cdev / set current device to i., disk
	jsr	r0,bread; 4872. / read block from disk (maximum block
				/ number allowed on device is 4872.)
				/ - (u.fofp) contains block number

wrk0:
	mov	$1,cdev / set current device to 1; disk
	jsr	r0,bwrite; 4872. / write block (u.fofp) on disk

rrf0:
	clr	cdev / set current device to 0., fixed head disk
	jsr	r0,bread; 1024. / read block (u.fofp) from fixed head
				/ disk (max. block number allowed on
				/ device is 1024.)

wrf0:
	clr	cdev / set current device to 0., fixed head disk
	jsr	r0,bwrite; 1024. / write block '(u.fofp)' on fixed head
				 / disk

bread: / read a block from a block structured device
	jsr	r0,tstdeve / error on special file I/O (only works on
			   / tape)
	mov	*u.fofp,r1 / move block number to r1
	mov	$2.-cold,-(sp) / "2-cold" to stack
1:
	cmp	r1,(r0)	/ is this block # greater than or equal to
			/ maximum block # allowed on device
	bhis	1f / yes, 1f (error)
	mov	r1,-(sp) / no, put block # on stack
	jsr	r0,preread / read in the block into an I/O buffer
	mov	(sp)+,r1 / return block # to r1
	inc	r1 / bump block # to next consecutive block
	dec	(sp) / "2-1-cold" on stack
	bgt	1b / 2-1-cold = 0?  No, go back and read in next block
1:
	tst	(sp)+ / yes, pop stack to clear off cold calculation
	mov	*u.fofp,r1 / restore r1 to initial value of the
			   / block #
       cmp     r1,(r0)+ / block # greater than or equal to maximum
       	                / block number allowed
       bhis    error10 / yes, error
       inc     *u.fofp / no, *u.fofp has next block number
       jsr     r0,preread / read in the block whose number is in r1
       bis     $40000,(r5) / set bit 14 of the 1st word of the I/O
       	                   / buffer
1:
       bit     $22000,(r5) / are 10th and 13th bits set (read bits)
       beq     1f / no
       cmp     cdev,$1 / disk or drum?
       ble     2f / yes
       tstb    uquant / is the time quantum = 0?
       bne     2f / no, 2f
       mov     r5,-(sp) / yes, save r5 (buffer address)
       jsr     r0,sleep; 31. / put process to sleep in channel 31 (tape)
       mov     (sp)+,r5 / restore r5
       br      1b / go back
2: / drum or disk
       jsr     r0,idle; s.wait+2 / wait
       br      1b
1: / 10th and 13th bits not set
       bic     $40000,(r5) / clear bit 14
       jsr     r0,tstdeve / test device for error (tape)
       add     $8,r5 / r5 points to data in I/O buffer
       jsr     r0,dioreg / do bookkeeping on u.count etc.
1: / r5 points to beginning of data in I/O buffer, r2 points to beginning
   / of users data
       movb    (r5)+,(r2)+ / move data from the I/O buffer
       dec     r3 / to the user's area in core starting at u.base
       bne     1b
       tst     u.count / done
       beq     1f / yes, return
       tst     -(r0) / no, point r0 to the argument again
       br      bread / read some more
1:
       mov     (sp)+,r0 / jump to routine that called readi
       jmp     ret

bwrite: / write on block structured device
       jsr     r0,tstdeve / test the device for an error
       mov     *u.fofp,r1 / put the block number in r1
       cmp     r1,(r0)+ / does block number exceed maximum allowable #
       bhis    error10 / yes, error
       inc     *u.fofp / no, increment block number
       jsr     r0,wslot / get an I/O buffer to write into
       jsr     r0,dioreg / do the necessary bookkeeping
1: / r2 points to the users data; r5 points to the I/O buffers data area
       movb    (r2)+,(r5)+ / ; r3, has the byte count
       dec     r3 / area to the I/O buffer
       bne     1b
       jsr     r0,dskwr / write it out on the device
       tst     u.count / done
       beq     1f / yes, 1f
       tst     -(r0) / no, point r0 to the argument of the call
       br      bwrite / go back and write next block
1:
       mov     (sp)+,r0 / return to routine that called writei
       jmp     ret
tstdeve: / check whether permanent error has occured on special file
         / I/O
       mov     cdev,r1 / only works on tape; r1 has device #
       tstb    deverr(r1) / test error bit of device
       bne     1f / error
       rts     r0 / device okay
1:
       clrb    deverr(r1) / clear error

error10:
       jmp     error / see 'error' routine

dioreg:
       mov     u.count,r3 / move char count to r3
       cmp     r3,$512. / more than 512. char?
       blos    1f / no, branch
       mov     $512.,r3 / yes, just take 512.
1:
       mov     u.base,r2 / put users base in r2
       add     r3,u.nread / add the number to be read to u.nread
       sub     r3,u.count / update count
       add     r3,u.base / update base
       rts     r0 / return

preread:
       jsr     r0,bufaloc / get a free I/O buffer (r1 has block number)
       br      1f / branch if block already in a I/O buffer
       bis     $2000,(r5) / set read bit (bit 100 in I/O buffer)
       jsr     r0,poke / perform the read
1:
       clr     *$ps / ps = 0
       rts     r0

dskrd:
       jsr     r0,bufaloc / shuffle off to bufaloc; get a free I/O buffer
               br 1f
       bis     $2000,(r5) / set bit 10 of word 1 of I/O queue entry
                          / for buffer
       jsr     r0,poke / just assigned in bufaloc, bit 10=1 says read
1:
       clr     *$ps
       bit     $22000,(r5) / if either bits 10, or 13 are 1; jump to idle
       beq     1f
       jsr     r0,idle; s.wait+2
       br      1b
1:
       add     $8,r5 / r5 points to first word of data in block just read
                     / in
       rts     r0

wslot:
       jsr     r0,bufaloc / get a free I/O buffer; pointer to first
               br 1f / word in buffer in r5
1:
       bit     $22000,(r5) / check bits 10, 13 (read, waiting to read)
       	                   / of I/O queue entry
       beq     1f / branch if 10, 13 zero (i.e., not reading, or waiting
       	          / to read)
       jsr     r0,idle; s.wait+2 / if buffer is reading or writing to read,
       	                         / idle
       br      1b / till finished
1:
       bis     $101000,(r5) / set bits 9, 15 in 1st word of I/O queue
                            / (write, inhibit bits)
       clr     *$ps / clear processor status
       add     $8,r5 / r5 points to first word in data area for this
       	             / block
       rts     r0

dskwr:
       bic     $100000,*bufp / clear bit 15 of I/O queue entry at
                             / bottom of queue

ppoke:
       mov     $340,*$ps
       jsr     r0,poke
       clr     *$ps
       rts     r0
poke:
       mov     r1,-(sp)
       mov     r2,-(sp)
       mov     r3,-(sp)
       mov     $bufp+nbuf+nbuf+6,r2 / r2 points to highest priority I/O
                                    / queue pointer
1:
       mov     -(r2),r1 / r1 points to an I/O queue entry
       bit     $3000,(r1) / test bits 9 and 10 of word 1 of I/O queue
                          / entry
       beq     2f / branch to 2f if both are clear
       bit     $130000,(r1) / test bits 12, 13, and 15
       bne     2f / branch if any are set
       movb    (r1),r3 / get device id
       tstb    deverr(r3) / test for errors on this device
       beq     3f / branch if no errors
       mov     $-1,2(r1) / destroy associativity
       clrb    1(r1) / do not do I/O
       br      2f
3:
       cmpb    r3,$1 / device id = 1; device is disk
       blt     prf / device id = 0; device is drum
       bgt     ptc / device id greater than or equal to 1; device is
       	           / dec tape
       bit     $2,active / test disk busy bit
       bne     2f / branch if bit is set
       bis     $2,active / set disk busy bit
       mov     r1,rkap / rkap points to current I/O queue entry for disk
       mov     2(r1),mq / put physical block number in mq
       mov     $12.,div / divide physical block number by 12.
       mov     $rkda+2,r3 /
       mov     ac,-(sp) / put remainder from divide on stack; gives
                        / sector number
       mov     $4,lsh / shift quotient 4 bits, to align with cyl and surf
                      / bits in rkda
       bis     mq,(sp) / or mq with sector; gives total disk address
       br      3f
prf: / drum
       bit     $1,active / test drum busy bit
       bne     2f / branch if bit is set
       bis     $1,active / set drum busy bit
       mov     r1,rfap / rfap points to current I/O queue entry for drum
       mov     $dae+2,r3
       clr     -(sp)
       movb    2(r1),1(sp) / move low byte of physical block number into
                           / high byte of stack
       clr     -(sp) / word
       movb    3(r1),(sp) / move high byte of physical block number into
                          / low byte of stack
       mov     (sp)+,-(r3) / load dae with high byte of physical block
                           / number
3:
       mov     (sp)+,-(r3) / load rkda register; load dar register
       mov     6(r1),-(r3) / load bus address register
       mov     4(r1),-(r3) / load word count register
       mov     $103,-(sp) / 103 indicates write operation when loaded
                          / in csr
       bit     $2000,(r1) / if bit 10 of word 1 of I/O queue entry is
                          / a one
       beq     3f / then read operation is indicated
       mov     $105,(sp) / 105 indicates read operation
3:
       mov     (sp)+,-(r3) / load csr with interrupt enabled, command, go
       br      seta
ptc: / tape I/O
       bit     $4,active
       bne     2f
       mov     tccm,r3
       swab    r3
       bic     $!7,r3
       add     $2,r3
       cmpb    r3,(r1)
       beq     3f
       movb    $1,tccm / stop transport if not same unit
3:
       bis     $4,active
       mov     r1,tcap
       mov     $20.,tcerrc
       mov     $tape1,tcstate
       movb    (r1),r3 / device
       sub     $2,r3 / now unit
       swab    r3
       bis     $103,r3 / now rbn,for,unit,ie
       mov     r3,tccm
 seta: / I/O queue bookkeeping; set read/write waiting bits.
       mov     (r1),r3 / move word 1 of I/O queue entry into r3
       bic     $!3000,r3 / clear all bits except 9 and 10
       bic     $3000,(r1) / clear only bits 9 and 10
       rol     r3
       rol     r3
       rol     r3
       bis     r3,(r1) / or old value of bits 9 and 10 with bits 12
       	               / and 13
2:
       cmp     r2,$bufp / test to see if entire I/O queue has been
                        / scanned
       bhi    1b
       mov    (sp)+,r3
       mov    (sp)+,r2
       mov    (sp)+,r1
       rts    r0

bufaloc:
       mov    r2,-(sp) / save r2 on stack
       mov    $340,*$ps / set processor priority to 7
1:
       clr    -(sp) / vacant buffer
       mov    $bufp,r2 / bufp contains pointers to I/O queue entrys
                       / in buffer area
2:
       mov    (r2)+,r5 / move pointer to word 1 of an I/O queue entry
                       / into r5
       bit    $173000,(r5) / lock+keep+active+outstanding
       bne    3f / branch when any of bits 9,10,12,13,14,15 are set
       	         / (i.e., buffer busy)
       mov    r2,(sp) / save pointer to last non-busy buffer found
       	              / points to word 2 of I/O queue entry)
3:
       cmpb   (r5),cdev / is device in I/O queue entry same as current
                        / device
       bne    3f
       cmp    2(r5),r1 / is block number in I/O queue entry, same as
       	               / current block number
       bne    3f
       tst    (sp)+ / bump stack pointer
       br     1f / use this buffer
3:
       cmp    r2,$bufp+nbuf+nbuf
       blo    2b / go to 2b if r2 less than bufp+nbuf+nbuf (all
                 / buffers not checked)
       mov    (sp)+,r2 / once all bufs are examined move pointer to
       	               / last free block
       bne    2f / if (sp) is non zero, i.e., if a free buffer is
       	         / found branch to 2f
       jsr    r0,idle; s.wait+2 / idle if no free buffers
       br     1b
2:
       tst    (r0)+ / skip if warmed over buffer
1:
       mov    -(r2),r5 / put pointer to word 1 of I/O queue entry in r5
       movb   cdev,(r5) / put current device number in I/O queue entry
       mov    r1,2(r5) / move block number into word 2 of I/O queue
/ entry
1:
       cmp     r2,$bufp / bump all entrys in bufp and put latest assigned
       blos    1f / buffer on the top (this makes if the lowest priority)
       mov     -(r2),2(r2) / job for a particular device
       br      1b
1:
       mov     r5,(r2)
       mov     (sp)+,r2 / restore r2
       rts     r0

tape: / dec tape interrupt
       jsr     r0,setisp / save registers and clockp on stack
       mov     tcstate,r3 / put state of dec tape in r3
       jsr     r0,trapt; tccm; tcap; 4 / busy bit
       mov     r3,pc / device control status register
       / if no errors, go to device state (an address)

taper: / dec tape error
       dec     tcerrc / decrement the number of errors
       bne     1f / if more than 1 branch
       movb    1(r2),r3 / r2+1 points to command register upper byte
       bic     $!7,r3 / clear all but bits 8-10 (Unit Selection)
       incb    deverr+2(r3) / set error bit for this tape unit
       br      tape3
1: / more than 1 error
       bit     $4000,(r2) / direction of tape
       beq     1f / if forward go to 1f
       bic     $4000,(r2) / reverse, set to forward
       mov     $tape1,tcstate / put tape 1 in the state
       br      0f
1: / put tape in reverse
       bis     $4000,(r2) / set tape to reverse direction
       mov     $tape2,tcstate / put tape 2 as the state
0:
       bis     $4,active / check active bit of tape
       movb    $103,(r2) / set read function and interrupt enable
       br      4f / go to retisp
tape1: / read bn forward
       mov     $tcdt,r0 / move address of data register to r0
       cmp     (r0),2(r1) / compare block addresses
       blt     0b / if lt, keep moving
       bgt     taper / if gt, reverse
       mov     6(r1),-(r0) / put bus address in tcba
       mov     4(r1),-(r0) / put word count in tcwc
       mov     $115,-(sp) / put end interrupt enable
       bit     $20000,(r1) / is "waiting to read bit" of I/O queue set?
       beq     1f / no,  1f
       mov     $105,(sp) / yes, put and interrupt enable
1:
       movb    (sp)+,(r2) / move function into command register (tccm)
       bis     $4,active / set active bit
       mov     $tape3,tcstate / get ready for I/O transfer
       br      4f / go to retisp (rti)

tape2: / read bn bakasswards
       mov     tcdt,r0 / r0 has contents of data register
       add     $3,r0 / overshoot
       cmp     r0,2(r1)
       bgt     0b / if gt keep reading
       br      taper / else reverse

tape3: / I/O transfer
       bic     $30000,(r1) / clear bits 12 and 13 of I/O queue entry
       jsr     r0,poke / do the I/O
       bit     $4,active / still busy see if pick up r-ahead, w-behind
       bne     1f / yes
       movb    $1,(r2) / no, indicate too bad
1:
       jsr     r0,wakeup; runq; 31. / wait up
       br      4f / retisp

drum: / interrupt handler
       jsr     r0,setisp / save r1,r2,r3, and clockp on the stack
       jsr     r0,trapt; dcs; rfap; 1 / check for stray interrupt or
                                      / error
               br 3f / no, error
       br      2f / error

disk:
       jsr     r0,setisp / save r1,r2,r3, and clockp on the stack
       jmp     *$0f
0:
       jsr     r0,trapt; rkcs; rkap; 2
       	       br 3f / no, errors
       mov     $115,(r2) / drive reset, errbit was set
       mov     $1f,0b-2 / next time jmp *$0f is executed jmp will be
                        / to 1f
       br      4f
1:
       bit     $20000,rkcs
       beq     4f / wait for seek complete
       mov     $0b,0b-2
       mov     rkap,r1
2:
       bit     $3000,(r1) / are bits 9 or 10 set in the 1st word of
                          / the disk buffer
       bne     3f / no, branch ignore error if outstanding
       inc     r1
       asr     (r1)
       asr     (r1)
       asr     (r1) / reissue request
       dec     r1
3:
       bic     $30000,(r1) / clear bits 12 and 13 in 1st word of buffer
       mov     ac,-(sp)
       mov     mq,-(sp) / put these on the stack
       mov     sc,-(sp)
       jsr     r0,poke
       mov     (sp)+,sc
       mov     (sp)+,mq / pop them off stack
       mov     (sp)+,ac
4:
       jmp     retisp / u4-3

trapt:                                   / r2 points to the
       mov     (r0)+,r2 / device control register
       mov     *(r0)+,r1 / transaction pointer points to buffer
       tst     (sp)+
       tstb    (r2) / is ready bit of dcs set?
       bge     4b / device still active so branch
       bit     (r0),active / was device busy?
       beq     4b / no, stray interrupt
       bic     (r0)+,active / yes, set active to zero
       tst     (r2) / test the err(bit is) of dcs
       bge     2f / if no error jump to 2f
       tst     (r0)+ / skip on error
 2:
       jmp     (r0)