title PASPSI - Tops-20 interrupt handling search monsym,pasunv twoseg entry psidef,psiena,psidis external oldpc.,chntb.,lockc.,level.,leav. filttb==filst1 ;current tty buffer filbct==filst2 ;tty byte count filbpt==filst3 ;tty byte pointer reloc 0 ttyb0: block ^D50 ;buffers for tty at 3 interrupt levels ttyb1: block ^D50 ttyb2: block ^D50 dispt: block ^D36 ;pascal routine to call for each channel reloc 400000 ttybuf: ttyb0 ;we get tty buffer from this, indexed ttyb1 ttyb2 disp: repeat ^D36,< ;chntab entries point to these adjstk p,24 pushj p,intmod > apracs==-20 intmod: movem 0,apracs(p) ;main dispatcher - save ac's hrli 0,1 hrri 0,apracs+1(p) blt 0,apracs+17(p) hrrz b,(p) ;place in disp we came from subi b,disp lsh b,-1 ;arguments for the pascal proc called: subi b,1 ;b _ index of interrupt hlrz a,chntb.(b) ;a _ interrupt level skipe d,lockc. ;interrupts locked out? jrst locked ;yes - defer it move c,oldpc.-1(a) ;c _ old pc caie b,6 ;see if arith overflow cain b,7 jrst ovrflw ; yes - ignore if in runtimes intok: hrrz e,oldpc.-1(a) ;see if this is deferred - addr only setz d, ; assume not cain e,leav. ;all deferred int's happen at this magic addr movei d,1 ;d _ deferred flag movei e,oldpc.-1(a) ;e _ addr of old pc movei f,apracs(p) ;f _ addr of ac save area push p,level. movem a,level. ;now at new level push p,fileol+tty## ;save the state of tty i/o push p,filcmp+tty## push p,filttb+tty## push p,filbct+tty## push p,filbpt+tty## setzm filcmp+tty## ;reinit tty movei t,1 movem t,fileol+tty## move t,ttybuf(b) movem t,filttb+tty## setzm filbct+tty## push p,filcmp+ttyout## ;likewise ttyoutput setzm filcmp+ttyout## push p,(p) ;top location gets garbaged pushj p,@dispt(b) pop p,(p) ;reverse the above pop p,filcmp+ttyout## pop p,filbpt+tty## pop p,filbct+tty## pop p,filttb+tty## pop p,filcmp+tty## pop p,fileol+tty## pop p,level. ignore: movem n,apracs+n(p) ;use new value of n if changed hrli 0,apracs+1(p) ;restore ac's hrri 0,1 blt 0,17 move 0,apracs(p) pop p,(p) ;restore stack adjstk p,-24 debrk ovrflw: hrrz t,c ;arith overflow - t _ pc cail t,safbeg## ;see if in runtimes caile t,safend## jrst .+2 jrst ignore camge n,.jbff## ;or in debugger jrst ignore jrst intok ;psidef(index,level,proc) psidef: cail b,0 ;channel 0 to 35 caile b,^D35 jrst badind cail c,1 ;level 1 to 3 caile c,3 jrst badlev hrl c,c move a,b lsh a,1 ;a _ index into disp hrri c,disp(a) ;c _ level,,dispatch movem c,chntb.(b) hrrzm d,dispt(b) popj p, ;psienable(index) psiena: cail b,0 caile b,^D35 jrst badind movn a,b movsi b,400000 ;bit 0 lsh b,(a) ;shift to requested bit position movei a,400000 ;this process aic popj p, ;psidisable(index) psidis: cail b,0 caile b,^D35 jrst badind movn a,b movsi b,400000 lsh b,(a) movei a,400000 dic popj p, badlev: hrroi a,[asciz /Psi: priority level must be 1 to 3 /] esout jrst endl badind: hrroi a,[asciz /Psi: channel must be 0 to 35 /] esout endl: haltf hrroi a,[asciz /Can't continue /] esout jrst endl locked: movsi t,400000 ;channel 0 movn a,b lsh t,(a) ;channel .b iorm t,(d) ;or into deferred int.word jrst ignore ;now ignore interrupt end