Research V1 development
[unix-history] / u6.s
/ 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