/ u4 -- unix setisp: mov r1,-(sp) mov r2,-(sp) mov r3,-(sp) mov clockp,-(sp) mov $s.syst+2,clockp jmp (r0) clock: / interrupt from 60 cycle clock mov r0,-(sp) / save r0 tst *$lks / restart clock? mov $s.time+2,r0 / increment the time of day inc (r0) bne 1f inc -(r0) 1: mov clockp,r0 / increment appropriate time category inc (r0) bne 1f inc -(r0) 1: mov $uquant,r0 / decrement user time quantum decb (r0) bge 1f / if less than 0 clrb (r0) / make it 0 1: / decrement time out counts return now if priority was not 0 cmp 4(sp),$200 / ps greater than or equal to 200 bge 2f / yes, check time outs tstb (r0) / no, user timed out? bne 1f / no cmpb sysflg,$-1 / yes, are we outside the system? bne 1f / no, 1f mov (sp)+,r0 / yes, put users r0 in r0 sys 0 / sysrele rti 2: / priority is high so just decrement time out counts mov $toutt,r0 / r0 points to beginning of time out table 2: tstb (r0) / is the time out? beq 3f / yes, 3f (get next entry) decb (r0) / no, decrement the time bne 3f / isit zero now? incb (r0) / yes, increment the time 3: inc r0 / next entry cmp r0,$touts / end of toutt table? blo 2b / no, check this entry mov (sp)+,r0 / yes, restore r0 rti / return from interrupt 1: / decrement time out counts; if 0 call subroutine mov (sp)+,r0 / restore r0 mov $240,*$ps / set processor priority to 5 jsr r0,setisp / save registers mov $touts-toutt-1,r0 / set up r0 as index to decrement thru / the table 1: tstb toutt(r0) / is the time out for this entry beq 2f / yes decb toutt(r0) / no, decrement the time bne 2f / is the time 0, now asl r0 / yes, 2 x r0 to get word index for tout entry jsr r0,*touts(r0) / go to appropriate routine specified in this asr r0 / touts entry; set r0 back to toutt index 2: dec r0 / set up r0 for next entry bge 1b / finished? , no, go back br retisp / yes, restore registers and do a rti ttyi: / console tty input interrupt routine jsr r0,setisp / save reg r1, r2, r3 mov *$tkb,r1 / r1 = char in tty reader buffer inc *$tks / set the reader enable bit bic $!177,r1 / clear upper 9 bits of the character (strip off / 8th bit of char) cmp r1,$'a-40 / is character upper case A,..., upper case Z. / note that blt 1f / lower case a is represented by 141, upper case by cmp r1,$'z-40 / 101; and lower case z by 172, upper / case Z by 132. bgt 1f / if not upper case, branch add $40,r1 / if upper case, calculate the representation of its / lower case counter part 1: cmp r1,$175 / char = "}"? Note: may be quit char (fs) beq 2f / yes 2f cmp r1,$177 / char = "del" ? beq 2f / yes, 2f jsr r0,putc; 0 / put char in r1 on clist entry br 1f movb r1,ttyoch / put char in ttyoch jsr r0,startty / load char in tty output data buffer cmp r1,$4 / r1 = "eot" beq 1f / yes, 1f cmp r1,$12 / r1 = "lf" beq 1f / yes 1f cmpb cc+0,$15. / are there less than 15 chars on the input list blo retisp / yes, return 1: jsr r0,wakeup; runq; 0 / no, wakeup the input process br retisp / return 2: / r1 = "}" or "delete" to get here mov tty+[ntty*8]-8+6,r2 / move console tty buffer address to r2 beq 2f / if 0, wakeall movb r1,6(r2) / move "}" or del into "interrupt char" / byte of buffer 2: jsr r0,wakeall / wakeup all sleeping processes br retisp / return wakeall: mov $39.,0f / flll arg2 of wakeup call wlth 39 1: jsr r0,wakeup; runq+4; 0:.. / wakeup the processes in the dec 0b / wait list; decrement arg2 bge 1b / if not done, go back rts r0 ttyo: / console typewriter output interrupt routine jsr r0,setisp / save registers jsr r0,startty / put a char on the console tty output buffer br retisp / restore registers retisp: mov (sp)+,clockp / pop values before interrupt off the stack mov (sp)+,r3 mov (sp)+,r2 mov (sp)+,r1 mov (sp)+,r0 rti / return from interrupt ppti: / paper tape lnput interrupt routine jsr r0,setisp / save registers movb pptiflg,r1 / place "pptiflg" in r1 jmp *1f(r1) / jump to location speclfled by value of "pptiflg" 1: retisp / file not open 1f / file just opened 2f / file normal retisp / file not closed 1: / file just opened tstb *$prs+1 / is error bit set in prs bge 1f / no jsr r0,pptito / place 10 in toutt entry for ppt input br retisp 1: movb $4,pptiflg / change "pptiflg" to indicate file "normal" 2: jsr r0,wakeup; runq+2; 2 / wakeup process for ppt input entry / in wlist tstb *$prs+1 / is error bit set blt 1f / yes mov *$prb,r1 / place contents ppt read buffer in r1 jsr r0,putc; 2 / place character in clist area for ppt input br .+2 / temp / if no space in clist character lost cmpb cc+2,$50. / character count in clist area for ppt lnput / greater than or equal to 50 bhis retisp / yes inc *$prs / no, set reader enable bit in prs br retisp 1: movb $6,pptiflg / set pptiflg to 6 to indicate error bit set br retisp /lpto: / jsr r0,setisp / jsr r0,starlpt / br retisp ppto: / paper tape output interrupt routine jsr r0,setisp / save registers jsr r0,starppt / get next character from clist, and output / if possible br retisp / pop register values from stack / starlpt: / cmpb cc+5.,$100. / bhi 1f / jsr r0,wakeup; runq+2; 5 /1: / tstb *$lps / bge 1f / jsr r0,getc; 5 / br 1f / mov r1,*$lpb / br starlpt /1: / rts r0 startty: / start or restart console tty output cmpb cc+1,$5. bhi 1f / branch to 1f when character count on tty (? input, / output) list is greater than 5. jsr r0,wakeup; runq+2; 1 1: tstb *$tps / test console output ready bit bge 2f / branch if ready bit is clear tstb toutt+0 / is toutt for console a zero bne 2f / if not; branch to 2f movb ttyoch,r1 / put character to be output in r1 bne 1f jsr r0,getc; 1 / if char is nul, get a char from console / output list br 2f / if console output list is empty, branch to 2f 1: clrb ttyoch mov r1,*$tpb / put character in console output register cmp r1,$12 / is char a line feed bne 1f movb $15,ttyoch / put a cr in ttyoch 1: cmp r1,$11 / char = ht bne 1f movb $15.,toutt+0 / set time out to 15 clock tics 1: cmp r1,$15 / char = cr bne 2f movb $15.,toutt+0 / set time out to 15 clock ticks 2: rts r0 pptito: / paper tape input touts subrouting cmpb pptiflg,$2 / does "pptiflg" indicate file just opened bne 1f / no, do nothing pyf movb $10.,toutt+1 / yes, place 10 in tout entry for tty input tstb *$prs+1 / is error bit set blt 1f / yes, return inc *$prs / no, set read enable bit 1: rts r0 starppt: / start ppt output cmpb cc+3,$10. / is character count for ppt output greater / than 10. bhi 1f / yes, branch jsr r0,wakeup; runq+2; 3 / no, wakeup process in wlist / entry for ppt input 1: tstb *$pps / is ready bit set in punch status word bge 1f / no, branch jsr r0,getc; 3 / yes, get next char in clist for pptout and / place in r1 br 1f / if none, branch mov r1,*$ppb / place character in ppt buffer 1: rts r0 wakeup: / wakeup processes waiting for an event by linking them to the / queue mov r1,-(sp) / put char on stack mov (r0)+,r2 / r2 points to a queue mov (r0)+,r3 / r3 = wait channel number movb wlist(r3),r1 / r1 contains process number in that wait / channel that was sleeping beq 2f / if 0 return, nothing to wakeup cmp r2,u.pri / is runq greater than or equal to users process / priority bhis 1f / yes, don't set time quantum to zero clrb uquant / time quantum = 0 1: clrb wlist(r3) / zero wait channel entry jsr r0,putlu / create a link from the last user on the Q / to this process number that got woken 2: mov (sp)+,r1 / restore r1 rts r0 sleep: / wait for event jsr r0,isintr / check to see if interrupt or quit from user br 2f / something happened / yes, his interrupt so return / to user mov (r0)+,r1 / put number of wait channel in r1 movb wlist(r1),-(sp) / put old process number in there, on / the stack movb u.uno,wlist(r1) / put process number of process to put / to sleep in there mov cdev,-(sp) / nothing happened in isintr so jsr r0,swap / swap out process that needs to sleep mov (sp)+,cdev / restore device jsr r0,isintr / check for interrupt of new process br 2f / yes, return to new user movb (sp)+,r1 / no, r1 = old process number that was originally / on the wait channel beq 1f / if 0 branch mov $runq+4,r2 / r2 points to lowest priority queue mov $300,*$ps / processor priority = 6 jsr r0,putlu / create link to old process number clr *$ps / clear the status; process priority = 0 1: rts r0 / return 2: jmp sysret / return to user isintr: mov r1,-(sp) / put number of wait channel on the stack mov r2,-(sp) / save r2 mov u.ttyp,r1 / r1 = pointer to buffer of process control / typewriter beq 1f / if 0, do nothing except skip return movb 6(r1),r1 / put interrupt char in the tty buffer in r1 beq 1f / if its 0 do nothing except skip return cmp r1,$177 / is interrupt char = delete? bne 3f / no, so it must be a quit (fs) tst u.intr / yes, value of u.intr determines handling / of interrupts bne 2f / if not 0, 2f. If zero do nothing. 1: tst (r0)+ / bump r0 past system return (skip) 4: mov (sp)+,r2 / restore r1 and r2 mov (sp)+,r1 rts r0 3: / interrupt char = quit (fs) tst u.quit / value of u.quit determines handling of quits beq 1b / u.quit = 0 means do nothing 2: / get here because either u.intr <> 0 or u.qult <> O mov $tty+6,r1 / move pointer to tty block into r1 1: / find process control tty entry in tty block cmp (r1),u.ttyp / is this the process control tty buffer? beq 1f / block found go to 1f add $8,r1 / look at next tty block cmp r1,$tty+[ntty*8]+6 / are we at end of tty blocks blo 1b / no br 4b / no process control tty found so go to 4b 1: mov $240,*$ps / set processor priority to 5 movb -3(r1),0f / load getc call argument; character llst / identifier inc 0f / increment 1: jsr r0,getc; 0:.. / erase output char list for control br 4b / process tty. This prevents a line of stuff / being typed out after you hit the interrupt / key br 1b