V1/u7.s
/ u7 -- unix
canon:
mov r5,r1 / move tty buffer address to r1
add $10.,r1 / add 10 to get start of data
mov r1,4(r5) / canp = 10(r5) / move buffer addr + 10 to 3rd
/ word in buffer (char. pointer)
clr 2(r5) / ncan / clear 2nd word in buffer, 0 char. count
1:
jsr r0,*(r0) / jump to arg get char off Q of characters, sleep
/ if none
jsr r0,cesc; 100 / test for @ (kill line)
br canon / character was @ so start over
jsr r0,cesc; 43 / test for # (erase last char. typed)
br 1b / character was #, go back
cmp r1,$4 / is char eot?
beq 1f / yes, reset and return
movb r1,*4(r5) / no, move char to address in 3rd word of buffer
/ (char. pointer)
inc 2(r5) / increment 2nd word (char. count)
inc 4(r5) / increment 3rd word (char. pointer)
cmp r1,$'\n / is char = newline
beq 1f / yes, 1f
cmp 2(r5),$120. / is byte count greater than or equal to 120
bhis 1f / yes, 1f
br 1b / no, get another char off the Q
1: / get here if line is full, a new line has been received or an eot
/ has been received
mov r5,r1 / move buffer address to r1
add $10.,r1 / add 10
mov r1,4(r5) / canp = 10(r5) / reset char pointer
tst (r0)+ / skip over argument
rts r0 / return
cesc: / test for erase or kill char
cmp r1,(r0)+ / char in r1 = erase or kill character?
bne 1f / no, skip return
tst 2(r5) / yes, is char. count = 0
beq 2f / yes, don't skip return
dec 2(r5) / no, decrement char count
dec 4(r5) / decrement character pointer
cmpb *4(r5),$'\\/ was previous character a "\"
bne 2f / no, don't skip
1:
tst (r0)+ / yes, skip
2:
rts r0 / return
ttych: / get characters from Q of characters inputted to tty
mov $240,*$ps / set processor priority to 5
jsr r0,getc; 0 / takes char. off clist and puts it in r1
br 1f / list is empty, go to sleep
clr *$ps / clear process priority
rts r0 / return
1: / list is empty
mov r5,-(sp) / save r5
jsr r0,sleep; 0 / put process to sleep in input wait channel
mov (sp)+,r5 / restore r5
br ttych / try again
pptic: / paper tape input control
mov $240,*$ps / set processor priority to five
cmpb cc+2,$30. / is character count for paper tape input in
/ clist greater than or equal to 30
bhis 1f / yes, branch
bit *$prs,$104200 / is there either an error, an unread char
/ in buffer, or reader busy
bne 1f / yes, don't enable reader
inc *$prs / set reader enable bit
1:
jsr r0,getc; 2 / get next character in clist for ppt input and
br 1f / place in r1; if no char in clist for ppt input
/ branch
tst (r0)+ / pop stack so that return will be four locations past
/ subroutine call
2:
clr *$ps / set process priority equal to zero
rts r0 / return
1:
cmpb pptiflg,$6 / does pptiflg indicate file "not closed"
beq 2b / yes, return to calling routine at instruction
/ immediately following jsr
jsr r0,sleep; 2 / no, all characters to be read in not yet in
/ clist, put process to sleep
br pptic
pptoc: / paper tape output control
mov $240,*$ps / set processor priority to five
cmpb cc+3,$50. / is character count for paper tape output in
/ clist greater than or equal to 50
bhis 1f / yes
jsr r0,putc; 3 / find place in freelist to assign ppt output
/ and place
br 1f / character in list; if none available branch to put
/ process to sleep
jsr r0,starppt / try to output character
clr *$ps / clear processor priority
rts r0 / return
1:
mov r1,-(sp) / place character on stack
jsr r0,sleep; 3 / put process to sleep
mov (sp)+,r1 / place character in r1
br pptoc / try again to place character in clist and output
/lptoc: / line printer output control
/ mov $240,*$ps / set processor priority to five
/ cmpb cc+5,$200. / is character count for printer greater than or
/ equal to 200
/ bhis 1f / yes
/ jsr r0,putc; 5 / find place in freelist to assign to printer
/ and place
br 1f / char in list, if none available branch to put
/ process to sleep
/ jsr r0,starlpt / try to output character
/ clr *$ps / set processor priority = 0
/ rts r0 / return
/1:
/ mov r1,-(sp) / place character on stack
/ jsr r0,sleep; 5 / put process to sleep
/ mov (sp)+,r1 / place character on stack
/ br lptoc
getc: / get a character off character list
mov (r0)+,r1 / put argument in getc call in r1 (char list id)
jsr r0,get
br 1f / empty char list return
decb cc(r1) / decrement number of char in char list
mov $-1,r1 / load minus 1 in r1
jsr r0,put / put char back on free list
movb clist-2(r2),r1 / put char in r1
tst (r0)+ / bump r0 for non blank char list return
1:
rts r0
putc:
mov r1,-(sp) / save char on stack
mov $-1,r1 / put free list list id in r1
jsr r0,get / take char off free list / clist slot taken
/ identified by r2
br 1f / branch when no chars in free list
mov (r0)+,r1 / put putc call arg in r1 (i.e., list identifier)
incb cc(r1) / increment character count for list (r1)
jsr r0,put / put clist entry on list
movb (sp),clist-2(r2) / put character in new entry
1:
tst (r0)+
mov (sp)+,r1
rts r0
get:
movb cf+1(r1),r2 / move current first char offset to r2
beq 2f / no characters in char list
tst (r0)+ / bump r0, second return
cmpb r2,cl+1(r1) / r2 equal to last char offset
beq 1f / yes, (i.e., entire char list scanned), branch to 1f
bic $!377,r2 / clear bits 8-15 in r2
asl r2 / multiply r2 by 2 to get offset in clist
movb clist-1(r2),cf+1(r1) / move next char in list pointer to
/ first char offset ptr
br 2f
1:
clrb cf+1(r1) / clear first char clist offset
clrb cl+1(r1) / clear last char clist offset
bic $!377,r2 / zero top half of r2
asl r2 / multiply r2 by 2
2:
rts r0
put:
asr r2 / divide r2 by 2; r2 is offset in clist
mov r2,-(sp) / save r2 on stack
movb cl+1(r1),r2 / move offset of last char in list (r1) into r2
beq 1f / offset = 0 then go to 1f (i.e., start a new list)
bic $!377,r2 / zero top half of r2
asl r2 / multiply offset by 2, r2 now has offset in clist
movb (sp),clist-1(r2) / link new list entry to current last
/ entry in list (r1)
br 2f
1:
movb (sp),cf+1(r1) / put new list entry offset into first char
/ offset of list (r1)
2:
mov (sp)+,r2 / pop stack into r2; offset of new list
/ entry in r2
movb r2,cl+1(r1) / make new list entry the last entry in list
/ (r1)
asl r2 / multiply r2 by 2; r2 has clist offset for new
/ list entry
rts r0
iopen: / open file whose i-number is in r1
tst r1 / write or read access?
blt 2f / write, go to 2f
jsr r0,access; 2 / get inode into core with read access
cmp r1,$40. / is it a special file
bgt 3f / no. 3f
mov r1,-(sp) / yes, figure out
asl r1
jmp *1f-2(r1) / which one and transfer to it
1:
otty / tty
oppt / ppt
sret / mem
sret / rf0
sret / rk0
sret / tap0
sret / tap1
sret / tap2
sret / tap3
sret / tap4
sret / tap5
sret / tap6
sret / tap7
ocvt / tty0
ocvt / tty1
ocvt / tty2
ocvt / tty3
ocvt / tty4
ocvt / tty5
ocvt / tty6
ocvt / tty7
error / crd
2: / check open write access
neg r1 / make inode number positive
jsr r0,access; 1 / get inode in 0 core
bit $40000,i.flgs / is it a directory?
bne 2f / yes, transfer (error)
cmp r1,$40. / no, is it a special file?
bgt 3f / no, return
mov r1,-(sp) / yes
asl r1
jmp *1f-2(r1) / figure out which special file it is
/ and transfer
1:
otty / tty
leadr / ppt
sret / mem
sret / rf0
sret / rk0
sret / tap0
sret / tap1
sret / tap2
sret / tap3
sret / tap4
sret / tap5
sret / tap6
sret / tap7
ocvt / tty0
ocvt / tty1
ocvt / tty2
ocvt / tty3
ocvt / tty4
ocvt / tty5
ocvt / tty6
ocvt / tty7
/ ejec / lpr
otty: / open console tty for reading or writing
mov $100,*$tks / set interrupt enable bit (zero others) in
/ reader status reg
mov $100,*$tps / set interrupt enable bit (zero others) in
/ punch status reg
mov tty+[ntty*8]-8+6,r5 / r5 points to the header of the
/ console tty buffer
incb (r5) / increment the count of processes that opened the
/ console tty
tst u.ttyp / is there a process control tty (i.e., has a tty
/ buffer header
bne sret / address been loaded into u.ttyp yet)? yes, branch
mov r5,u.ttyp / no, make the console tty the process control
/ tty
br sret / ?
sret:
clr *$ps / set processor priority to zero
mov (sp)+,r1 / pop stack to r1
3:
rts r0
oppt: / open paper tape for reading or writing
mov $100,*$prs / set reader interrupt enable bit
tstb pptiflg / is file already open
bne 2f / yes, branch
1:
mov $240,*$ps / no, set processor priority to 5
jsr r0,getc; 2 / remove all entries in clist
br .+4 / for paper tape input and place in free list
br 1b
movb $2,pptiflg / set pptiflg to indicate file just open
movb $10.,toutt+1 / place 10 in paper tape input tout entry
br sret
2:
jmp error / file already open
iclose: / close file whose i-number is in r1
tst r1 / test i-number
blt 2f / if neg., branch
cmp r1,$40. / is it a special file
bgt 3b / no, return
mov r1,-(sp) / yes, save r1 on stack
asl r1
jmp *1f-2(r1) / compute jump address and transfer
1:
ctty / tty
cppt / ppt
sret / mem
sret / rf0
sret / rk0
sret / tap0
sret / tap1
sret / tap2
sret / tap3
sret / tap4
sret / tap5
sret / tap6
sret / tap7
ccvt / tty0
ccvt / tty1
ccvt / tty2
ccvt / tty3
ccvt / tty4
ccvt / tty5
ccvt / tty6
ccvt / tty7
error / crd
2: / negative i-number
neg r1 / make it positive
cmp r1,$40. / is it a special file
bgt 3b / no. return
mov r1,-(sp)
asl r1 / yes. compute jump address and transfer
jmp *1f-2(r1)
1:
ctty / tty
leadr / ppt
sret / mem
sret / rf0
sret / rk0
sret / tap0
sret / tap1
sret / tap2
sret / tap3
sret / tap4
sret / tap5
sret / tap6
sret / tap7
ccvt / tty0
ccvt / tty1
ccvt / tty2
ccvt / tty3
ccvt / tty4
ccvt / tty5
ccvt / tty6
ccvt / tty7
/ ejec / lpr
ctty: / close console tty
mov tty+[ntty*8]-8+6,r5 / point r5 to the console tty buffer
decb (r5) / dec number of processes using console tty
br sret / return via sret
cppt: / close paper tape
clrb pptiflg / set pptiflg to indicate file not open
1:
mov $240,*$ps /set process or priority to 5
jsr r0,getc; 2 / remove all ppt input entries from clist
/ and assign to free list
br sret
br 1b
/ejec:
/ mov $100,*$lps / set line printer interrupt enable bit
/ mov $14,r1 / 'form feed' character in r1 (new page).
/ jsr r0,lptoc / space the printer to a new page
/ br sret / return to caller via 'sret'
leadr: / produce paper tape leader
mov $100,*$pps / set paper tape punch interrupt enable
mov $100.,-(sp) / 101. characters of 'nul' will be output as
/ leader
1:
clr r1 / r1 contains a 'nul' character
jsr r0,pptoc / output the 'nul' character
dec (sp)
bge 1b / last leader character output? no, branch
tst (sp)+ / bump stack pointer
br sret / return to caller via 'sret'
sysmount: / mount file system; args special; name
jsr r0,arg2 / get arguments special and name
tst mnti / is the i-number of the cross device file zero?
bne errora / no, error
jsr r0,getspl / get special files device number in r1
mov (sp)+,u.namep / put the name of file to be placed on the
/ device
mov r1,-(sp) / save the device number
jsr r0,namei / get the i-number of the file
br errora
mov r1,mnti / put it in mnti
1:
tstb sb1+1 / is 15th bit of I/O queue entry for dismountable
/ device set?
bne 1b / (inhibit bit) yes, skip writing
mov (sp),mntd / no, put the device number in mntd
movb (sp),sb1 / put the device number in the lower byte of the
/ I/O queue entry
mov (sp)+,cdev / put device number in cdev
bis $2000,sb1 / set the read bit
jsr r0,ppoke / read in entire file system
1:
tstb sb1+1 / done reading?
bne 1b / no, wait
br sysreta / yes
sysumount: / special dismount file system
jsr r0,arg; u.namep / point u.namep to special
jsr r0,getspl / get the device number in r1
cmp r1,mntd / is it equal to the last device mounted?
bne errora / no error
1:
tstb sb1+1 / yes, is the device still doing I/O (inhibit
/ bit set)?
bne 1b / yes, wait
clr mntd / no, clear these
clr mnti
br sysreta / return
getspl: / get device number from a special file name
jsr r0,namei / get the i-number of the special file
br errora / no such file
sub $4,r1 / i-number-4 rk=1,tap=2+n
ble errora / less than 0? yes, error
cmp r1,$9. / greater than 9 tap 7
bgt errora / yes, error
rts r0 / return with device number in r1
errora:
jmp error / see 'error' routine
sysreta:
jmp sysret / see 'sysret' routine