; Interrupt.Asm ; CauseInterrupt, DestroyInterrupt, (+ interrupt handler) ; Copyright Xerox Corporation 1979 ; Copyright Xerox Corporation 1979 ; last modified September 4, 1979 2:30 PM by Taft .ent CauseInterrupt .ent DestroyInterrupt .ent interruptPrologue .ent interruptsActive .ent interruptFinish .ent savedUserFinishProc .bext lvUserFinishProc .srel CauseInterrupt: .Cause DestroyInterrupt: .Destroy interruptPrologue: .Prologue interruptsActive: 0 ; Bits that I have turned on! interruptFinish: .IntFin savedUserFinishProc: -1 ; -1 means nothing yet saved .zrel InterruptEntry: .IntEnt .nrel 0 ; Sacrifice to Bldr ; Offsets of things in IST (Interrupt Stack); same as in InterruptInit.Bcpl ; Prologue is in 0, 1 R=2 ; Point where AC3 will point .AC0=2 ; Machine state.... .AC1=3 .AC2=4 .AC3=5 .PC=6 .StkMin=7 ; Old stack min .ACT=8. ; Active lshift 1 + carry ; Context to run the guy in: .NMask=9. ; New interrupt mask .NStack=10. .NStkMin=11. .InitPC=12. ; Procedure to call .StkBot=13. ; Bottom of stack -- place 335 will point to. ; Bcpl runtime location StkMin=335 ; The following 2 prologue words are recorded in the IST. ; When an interrupt fires, control transfers to the IST, which ; saves AC3 and jsr's to common code for saving the remainder ; of the state .Prologue: sta 3,.Prologue+.AC3 ; State-saving prologue in each IST jsr @InterruptEntry ;----------------------------------------------------------------- .IntEnt: ;----------------------------------------------------------------- sta 2,.AC2-R,3 ; Common code to save state sta 1,.AC1-R,3 sta 0,.AC0-R,3 lda 0,@.intPC sta 0,.PC-R,3 lda 0,StkMin sta 0,.StkMin-R,3 lda 0,@.Active ; Save current active interrupts movl 0 1 ; Save carry (bit 0 of active unused) sta 1,.ACT-R,3 lda 1,.NMask-R,3 ; Interrupts to leave on. and 1,0 ; Compute new active sta 0,@.Active ; And put it down. eir ; Now can proceed. ; Set up new context, and call the specified procedure. ; Interrupt will be dismissed when procedure returns. lda 2,.NStkMin-R,3 sta 2,StkMin lda 2,.NStack-R,3 jsr @.InitPC-R,3 ; Call procedure 0 ; With no arguments. ; Restore state that was saved in the IST, and dismiss interrupt. lda 3 0 2 ; Recover IST pointer dir ; Prepare to restore state lda 1,.ACT-R,3 movzr 1 1 ; Restore carry sta 1,@.Active ; Restore active lda 1,.StkMin-R,3 sta 1,StkMin lda 1,.PC-R,3 sta 1,@.intPC lda 0,.AC0-R,3 lda 1,.AC1-R,3 lda 2,.AC2-R,3 lda 3,.AC3-R,3 bri ; Off to see the world .intPC: 500 ; Place PC saved on interrupt .Active: 453 ; Active interrupts word ;----------------------------------------------------------------- .IntFin: ;----------------------------------------------------------------- ; called on Finish or Abort to disable any interrupts that ; we may have turned on. sta 3 1 2 lda 0,@.IntAct ; Turn off interrupts that are on. jsr .Destroy 1 lda 0,@.savedUserFinishProc ; Restore old finish routine lda 3,@.lvUserFinishProc sta 0,0,3 lda 3 1 2 jmp 1 3 .IntAct: interruptsActive .savedUserFinishProc: savedUserFinishProc .lvUserFinishProc: lvUserFinishProc ;----------------------------------------------------------------- .Destroy: ;----------------------------------------------------------------- ; DestroyInterrupt(mask) ; Turn off interrupt channel(s) designated by mask com 0,0 ; Prepare to "and" with active dir lda 1,@.Active and 0,1 sta 1,@.Active ; All gone! eir lda 1 @.IntAct ; Update our record and 0 1 sta 1 @.IntAct jmp 1,3 ; Return ;----------------------------------------------------------------- .Cause: ;----------------------------------------------------------------- ; CauseInterrupt(mask) ; Initiate interrupt on channel(s) designated by mask com 0,0 ; Prepare to "or" with wakeups waiting dir lda 1,@.Wakeups and 0,1 adc 0,1 sta 1,@.Wakeups eir jmp 1,3 .Wakeups: 452 ;----------------------------------------------------------------- ; DisableInterrupts() and EnableInterrupts() ;----------------------------------------------------------------- ; These are provided here so they are still available ; even if you junta the ones in the operating system .ent DisableInterrupts, EnableInterrupts .srel DisableInterrupts: .Disable EnableInterrupts: .Enable .nrel .Disable: #61013 ; return true if they were on mkzero 0 0 skp mkminusone 0 0 jmp 1,3 .Enable: eir jmp 1,3 .end