home *** CD-ROM | disk | FTP | other *** search
-
- ; QINT.ASM
- ;
- ; handle= OpenQInts()
- ; CloseQInts(handle:A0)
- ; SetQPri(handle:D0, pri:D1)
- ; SetQVector(handle:D0, vector:D1, signo:D2, arg:D3, pri:A0)
-
- public _lOpenQInts
- public _lCloseQInts
- public _lSetQPri
- public _lSetQVector
-
- public _LVOFindTask
- public _LVOAllocMem
- public _LVOFreeMem
- public _LVOForbid
- public _LVOPermit
- public _LVODisable
- public _LVOEnable
- public _LVOEnqueue
- public _LVORemove
- public _LVOSetSignal
- public _LVOSetExcept
-
- QINT_SIZE EQU 32
-
- QINT_NODE EQU 0
- QINT_VECTOR EQU 14
- QINT_SIGMASK EQU 18
- QINT_ARG EQU 22
- QINT_UNUSED EQU 26
-
- HAN_SIZE EQU 36+32*QINT_SIZE
- HAN_A4 EQU 0
- HAN_A5 EQU 4
- HAN_EXCODE EQU 8
- HAN_EXDATA EQU 12
- HAN_INTS EQU 16
- HAN_INHAN EQU 18
- HAN_PRI EQU 20
- HAN_LIST EQU 22
- HAN_QINT EQU 36
-
- MEMF_CLEAR EQU $10000
- MEMF_PUBLIC EQU $1
-
- LH_HEAD EQU 0
- LH_TAIL EQU 4
- LH_TAILPRED EQU 8
-
- LN_TYPE EQU 8
- LN_PRI EQU 9
-
- TC_EXCEPTCODE EQU 42
- TC_EXCEPTDATA EQU 38
-
-
- _lOpenQInts:
- movem.l D2/D3/A2/A6,-(sp)
- move.l 4,A6
- move.l #HAN_SIZE,D0
- move.l #MEMF_CLEAR|MEMF_PUBLIC,D1
- jsr _LVOAllocMem(A6)
- tst.l D0
- beq .oqi1
- move.l D0,A2
- move.b #-128,HAN_PRI(A2)
- movem.l A4/A5,HAN_A4(A2)
- lea.l HAN_LIST+LH_HEAD(A2),A0
- lea.l HAN_LIST+LH_TAIL(A2),A1
- move.l A1,(A0)
- move.l A0,LH_TAILPRED(A0)
- .oqi1 movem.l (sp)+,D2/D3/A2/A6
- rts
-
- _lCloseQInts: ; A0 = handle
- movem.l D2/D3/A2/A6,-(sp)
- move.l 4,A6
- move.l A0,A2 ; A2 = handle
- move.l A0,D0 ; skip if null
- beq .cqi1
- moveq.l #31,D3 ; D3 = sig number.
- .cqi2 move.w D3,-(sp)
- move.l D3,D2 ; SetQVector(han, NULL, sig#, 0, 0)
- move.l A2,D0 ; D0 D1 D2 D3 A0
- moveq.l #0,D1
- move.l D1,D3
- move.l D1,A0
- jsr _lSetQVector
- move.w (sp)+,D3
- dbf D3,.cqi2
-
- .cqi1 movem.l (sp)+,D2/D3/A2/A6
- rts
-
-
-
- ; _EXCEPT , Exception handler.
- ;
- ;entry:
- ; D0 = exceptions that occured
- ; A1 = Handle
- ;
- ;auto:
- ; A2 = Handle
- ; A4/A5 = Possible Global Base Registers
- ; D4 = Bit# count
- ; D6 = Exceptions that occured
-
-
- _except:
- move.l 4,A6 ;A6 = Exec Base
- move.l D0,D6 ;D6 = Exception Bit Mask
- movem.l HAN_A4(A1),A4/A5;get global base register(s).
- move.l A1,A2 ;A2 = HANDLE BASE
-
- ; Queue any exceptions which are interrupts. Exceptions
- ; for interrupts which are queued are NOT reenabled until
- ; they are actually run.
- ;
- ; Note that in the loop we must loop to .ex2 to decrement
- ; D4, which doesn't occur when we find a '1'. The Z bit
- ; must be set when we loop to .ex2
-
- .ex0 moveq.l #31,D4 ;D4 = BIT NUMBER
- .ex1 btst.l D4,D6 ; test bits
- .ex2 dbne D4,.ex1 ; until found a '1'
- beq .ex10 ;or loop exhausted (D4 == -1)
-
- move.l D4,D5 ;Calculate address of QINT.
- asl.l #5,D5 ;D5 = index * sizeof(QINT)
- pea.l HAN_QINT(A2)
- add.l (sp)+,D5 ; + Base of QINT array
- move.l D5,A3 ;A3 = QINT address
- tst.l QINT_VECTOR(A3) ;Is this exception vectored?
- beq .ex2 ;no, somebody else owns it
-
- .ex3 bclr.l D4,D6 ;clear exception bit.
- jsr _LVOForbid(A6) ;Important operation!
- move.l A3,A1 ;A1 = node
- lea.l HAN_LIST(A2),A0 ;A0 = List Base
- move.b #5,LN_TYPE(A1) ;mark node as being queued
- jsr _LVOEnqueue(A6)
- jsr _LVOPermit(A6) ;enable exceptions
- clr.w D7 ;Force Z cc set.
- bra .ex2 ;loop (force decrement/loop)
-
- ; Call the handler. The handler is allowed to trash
- ; everything except D6/A7. Called with A2 = Handle,
- ; A6 = Exec Base
-
- .ex10 tst.w HAN_INHAN(A2) ;no need to call handler?
- bne .ex11
- bsr _handler ;call handler
- .ex11 move.l D6,D0 ;D0 = exception mask
- beq .ex12 ;we processed all exceptions
- move.l HAN_EXCODE(A2),A0 ;somebody else owns some exceptions
- move.l HAN_EXDATA(A2),A1 ;restore exception data pointer
- jmp (A0) ;call him with remaining exceptions.
- .ex12 rts
-
- ;entry:
- ; A2 = Handle
- ; A4/A5 = Possible Global Base Registers
- ; A6 = EXEC base
- ;
- ;auto:
- ; A2 = Handle;
- ; A3 = Qint
- ; A4/A5 = GBRs
- ; A6 = EXEC base
- ; D4 = savepri
-
- _handler:
- move.b #1,HAN_INHAN(A2)
- jsr _LVOForbid(A6)
- .hloop move.l HAN_LIST+LH_HEAD(A2),A3
- lea.l HAN_LIST+LH_TAIL(A2),A0
- cmp.l A0,A3 ;List is empty
- beq .hbreak
- move.b HAN_PRI(A2),D4 ;Check priority of node
- cmp.b QINT_NODE+LN_PRI(A3),D4
- bgt .hbreak ;savepri > qintpri
- move.l A3,A1 ;A1 = node to remove
- jsr _LVORemove(A6)
- move.b #0,QINT_NODE+LN_TYPE(A3)
- move.b QINT_NODE+LN_PRI(A3),HAN_PRI(A2)
- jsr _LVOPermit(A6)
- move.l QINT_ARG(A3),-(sp)
- move.l QINT_VECTOR(A3),A0
- jsr (A0)
- move.l 4,A6
- addq.l #4,sp
- move.b D4,HAN_PRI(A2)
- tst.l QINT_VECTOR(A3) ;Reenable the exception
- beq .h1 ;only if the vector still
- move.l QINT_SIGMASK(A3),D0 ;exists.
- move.l D0,D1
- jsr _LVOSetExcept(A6)
- .h1 jsr _LVOForbid(A6)
- bra .hloop
-
- .hbreak moveq.l #0,D2
- move.b D2,HAN_INHAN(A2)
- jsr _LVOPermit(A6)
- move.l D2,D0
- move.l D2,D1
- jsr _LVOSetExcept(A6)
- rts
-
- ; SetQVector()
- ;
- ; D0 = handle (copy to A2)
- ; D1 = vector (copy to A3)
- ; D2 = signo
- ; D3 = arg (copy to D5)
- ; A0 = pri
- ;
- ; A2 = handle
- ; A3 = vector
- ; A4 = qint
- ; A5 = task
- ;
- ; D2 = pri
- ; D3 = sigmask
- ; D4 = oldvector
- ; D5 = arg
- ; D6 =
- ; D7 =
-
- _lSetQVector:
- movem.l D2-D7/A2-A6,-(sp)
- move.l 4,A6
- move.l D0,A2 ; A2 = Handle
- move.l D1,A3 ; A3 = Vector
- move.l D3,D5 ; D5 =
-
- moveq.l #0,D3 ; D3 = signal mask
- bset.l D2,D3 ; D2 = signal
- asl.l #5,D2 ; A4 = qint (han->QInt + signo)
- add.l #HAN_QINT,D2
- add.l A2,D2
- move.l D2,A4 ; A4 = QINT
- move.l A0,D2 ; D2 = priority
- move.w #0,A1 ; A5 = task
- jsr _LVOFindTask(A6)
- move.l D0,A5
-
- jsr _LVOForbid(A6) ; Forbid
- move.l QINT_VECTOR(A4),D4 ; D4 = oldvector
- move.l A3,D0
- bne .sq100
-
- ; If new vector is NULL, remove old vector if it exists.
-
- tst.l D4
- beq .sqdone
- moveq.l #0,D0
- move.l D3,D1
- jsr _LVOSetExcept(A6)
- cmp.b #5,QINT_NODE+LN_TYPE(A4)
- bne .sq1
- move.l A4,A1
- jsr _LVORemove(A6)
- move.b #0,QINT_NODE+LN_TYPE(A4)
- .sq1 sub.w #1,HAN_INTS(A2)
- bne .sq2
- jsr _LVODisable(A6)
- move.l HAN_EXCODE(A2),TC_EXCEPTCODE(A5)
- move.l HAN_EXDATA(A2),TC_EXCEPTDATA(A5)
- jsr _LVOEnable(A6)
- .sq2 bra .sqdone
-
- ; If new vector not null, replace (possibly NULL) old vector
-
- .sq100 tst.l D4
- bne .sq150
- add.w #1,HAN_INTS(A2) ; oldvector is null, setup task
- cmp.w #1,HAN_INTS(A2)
- bne .sq150
- jsr _LVODisable(A6)
- move.l TC_EXCEPTCODE(A5),HAN_EXCODE(A2)
- move.l TC_EXCEPTDATA(A5),HAN_EXDATA(A2)
- move.l #_except,TC_EXCEPTCODE(A5)
- move.l A2,TC_EXCEPTDATA(A5)
- jsr _LVOEnable(A6)
-
- .sq150 move.l D5,QINT_ARG(A4)
- move.b D2,QINT_NODE+LN_PRI(A4)
- move.l D3,QINT_SIGMASK(A4)
- move.l D3,D0
- move.l D3,D1
- jsr _LVOSetExcept(A6)
- bra .sqdone
-
- .sqdone move.l A3,QINT_VECTOR(A4)
- jsr _LVOPermit(A6)
- moveq.l #0,D0
- move.l D0,D1
- jsr _LVOSetExcept(A6)
- move.l D4,D0
- movem.l (sp)+,D2-D7/A2-A6
- rts
-
- ; SetQPri
- ;
- ; D0 = handle
- ; D1 = newpri
- ;
- ; A2 = handle
- ; D2 = newpri
- ; D3 = oldpri
- _lSetQPri:
- movem.l D2/D3/A2/A6,-(sp)
- move.l 4,A6
- move.l D0,A2
- move.l D1,D2
- jsr _LVODisable(A6)
- move.b HAN_PRI(A2),D3
- move.b D2,HAN_PRI(A2)
- jsr _LVOEnable(A6)
- cmp.b D2,D3
- ble .sqpdone ; D3 <= D2 (old <= new)
- lea.l HAN_LIST+LH_TAIL(A2),A0
- cmp.l HAN_LIST+LH_HEAD(A2),A0
- beq .sqpdone
-
- movem.l D4/A3,-(sp)
- jsr _handler ;A2 = handle, A6 = execbase
- movem.l (sp)+,D4/A3
- .sqpdone:
- moveq.l #0,D0
- move.b D3,D0
- movem.l (sp)+,D2/D3/A2/A6
- rts
-
-