clock: / interrupt from 60 cycle clock
tst *$lks / restart clock?
mov $s.time+2,r0 / increment the time of day
mov clockp,r0 / increment appropriate time category
mov $uquant,r0 / decrement user time quantum
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?
cmpb sysflg,$-1 / yes, are we outside the system?
mov (sp)+,r0 / yes, put users r0 in r0
2: / priority is high so just decrement time out counts
mov $toutt,r0 / r0 points to beginning of time out table
tstb (r0) / is the time out?
beq 3f / yes, 3f (get next entry)
decb (r0) / no, decrement the time
incb (r0) / yes, increment the time
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
tstb toutt(r0) / is the time out for this entry
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
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
cmp r1,$'a-40 / is character upper case A,..., upper case Z.
blt 1f / lower case a is represented by 141, upper case by
cmp r1,$'z-40 / 101; and lower case z by 172, upper
bgt 1f / if not upper case, branch
add $40,r1 / if upper case, calculate the representation of its
/ lower case counter part
cmp r1,$175 / char = "}"? Note: may be quit char (fs)
cmp r1,$177 / char = "del" ?
jsr r0,putc; 0 / put char in r1 on clist entry
movb r1,ttyoch / put char in ttyoch
jsr r0,startty / load char in tty output data buffer
cmpb cc+0,$15. / are there less than 15 chars on the input list
jsr r0,wakeup; runq; 0 / no, wakeup the input process
2: / r1 = "}" or "delete" to get here
mov tty+[ntty*8]-8+6,r2 / move console tty buffer address to r2
movb r1,6(r2) / move "}" or del into "interrupt char"
jsr r0,wakeall / wakeup all sleeping processes
mov $39.,0f / flll arg2 of wakeup call wlth 39
jsr r0,wakeup; runq+4; 0:.. / wakeup the processes in the
dec 0b / wait list; decrement arg2
bge 1b / if not done, go back
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
mov (sp)+,clockp / pop values before interrupt off the stack
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"
tstb *$prs+1 / is error bit set in prs
jsr r0,pptito / place 10 in toutt entry for ppt input
movb $4,pptiflg / change "pptiflg" to indicate file "normal"
jsr r0,wakeup; runq+2; 2 / wakeup process for ppt input entry
tstb *$prs+1 / is error bit set
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
inc *$prs / no, set reader enable bit in prs
movb $6,pptiflg / set pptiflg to 6 to indicate error bit set
ppto: / paper tape output interrupt routine
jsr r0,setisp / save registers
jsr r0,starppt / get next character from clist, and output
br retisp / pop register values from stack
/ jsr r0,wakeup; runq+2; 5
startty: / start or restart console tty output
bhi 1f / branch to 1f when character count on tty (? input,
/ output) list is greater than 5.
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
jsr r0,getc; 1 / if char is nul, get a char from console
br 2f / if console output list is empty, branch to 2f
mov r1,*$tpb / put character in console output register
cmp r1,$12 / is char a line feed
movb $15,ttyoch / put a cr in ttyoch
movb $15.,toutt+0 / set time out to 15 clock tics
movb $15.,toutt+0 / set time out to 15 clock ticks
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
inc *$prs / no, set read enable bit
starppt: / start ppt output
cmpb cc+3,$10. / is character count for ppt output greater
jsr r0,wakeup; runq+2; 3 / no, wakeup process in wlist
tstb *$pps / is ready bit set in punch status word
jsr r0,getc; 3 / yes, get next char in clist for pptout and
mov r1,*$ppb / place character in ppt buffer
wakeup: / wakeup processes waiting for an event by linking them to the
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
bhis 1f / yes, don't set time quantum to zero
clrb uquant / time quantum = 0
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
mov (sp)+,r1 / restore r1
jsr r0,isintr / check to see if interrupt or quit from user
br 2f / something happened / yes, his interrupt so return
mov (r0)+,r1 / put number of wait channel in r1
movb wlist(r1),-(sp) / put old process number in there, on
movb u.uno,wlist(r1) / put process number of process to put
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
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
jmp sysret / return to user
mov r1,-(sp) / put number of wait channel on the stack
mov u.ttyp,r1 / r1 = pointer to buffer of process control
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
bne 2f / if not 0, 2f. If zero do nothing.
tst (r0)+ / bump r0 past system return (skip)
mov (sp)+,r2 / restore r1 and r2
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
br 4b / no process control tty found so go to 4b
mov $240,*$ps / set processor priority to 5
movb -3(r1),0f / load getc call argument; character llst
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