/ 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