home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 177.lha / DRes_v1.3 / src / qint.asm < prev    next >
Encoding:
Assembly Source File  |  1988-04-28  |  8.2 KB  |  338 lines

  1.  
  2. ;   QINT.ASM
  3. ;
  4. ;   handle= OpenQInts()
  5. ;        CloseQInts(handle:A0)
  6. ;        SetQPri(handle:D0, pri:D1)
  7. ;        SetQVector(handle:D0, vector:D1, signo:D2, arg:D3, pri:A0)
  8.  
  9.         public    _lOpenQInts
  10.         public    _lCloseQInts
  11.         public    _lSetQPri
  12.         public    _lSetQVector
  13.  
  14.         public    _LVOFindTask
  15.         public    _LVOAllocMem
  16.         public    _LVOFreeMem
  17.         public    _LVOForbid
  18.         public    _LVOPermit
  19.         public    _LVODisable
  20.         public    _LVOEnable
  21.         public    _LVOEnqueue
  22.         public    _LVORemove
  23.         public    _LVOSetSignal
  24.         public    _LVOSetExcept
  25.  
  26. QINT_SIZE    EQU    32
  27.  
  28. QINT_NODE    EQU    0
  29. QINT_VECTOR    EQU    14
  30. QINT_SIGMASK    EQU    18
  31. QINT_ARG    EQU    22
  32. QINT_UNUSED    EQU    26
  33.  
  34. HAN_SIZE    EQU    36+32*QINT_SIZE
  35. HAN_A4        EQU    0
  36. HAN_A5        EQU    4
  37. HAN_EXCODE    EQU    8
  38. HAN_EXDATA    EQU    12
  39. HAN_INTS    EQU    16
  40. HAN_INHAN    EQU    18
  41. HAN_PRI     EQU    20
  42. HAN_LIST    EQU    22
  43. HAN_QINT    EQU    36
  44.  
  45. MEMF_CLEAR    EQU    $10000
  46. MEMF_PUBLIC    EQU    $1
  47.  
  48. LH_HEAD     EQU    0
  49. LH_TAIL     EQU    4
  50. LH_TAILPRED    EQU    8
  51.  
  52. LN_TYPE     EQU    8
  53. LN_PRI        EQU    9
  54.  
  55. TC_EXCEPTCODE    EQU    42
  56. TC_EXCEPTDATA    EQU    38
  57.  
  58.  
  59. _lOpenQInts:
  60.         movem.l D2/D3/A2/A6,-(sp)
  61.         move.l  4,A6
  62.         move.l  #HAN_SIZE,D0
  63.         move.l  #MEMF_CLEAR|MEMF_PUBLIC,D1
  64.         jsr     _LVOAllocMem(A6)
  65.         tst.l   D0
  66.         beq     .oqi1
  67.         move.l  D0,A2
  68.         move.b  #-128,HAN_PRI(A2)
  69.         movem.l A4/A5,HAN_A4(A2)
  70.         lea.l   HAN_LIST+LH_HEAD(A2),A0
  71.         lea.l   HAN_LIST+LH_TAIL(A2),A1
  72.         move.l  A1,(A0)
  73.         move.l  A0,LH_TAILPRED(A0)
  74. .oqi1        movem.l (sp)+,D2/D3/A2/A6
  75.         rts
  76.  
  77. _lCloseQInts:                 ; A0 = handle
  78.         movem.l D2/D3/A2/A6,-(sp)
  79.         move.l  4,A6
  80.         move.l  A0,A2        ; A2 = handle
  81.         move.l  A0,D0        ; skip if null
  82.         beq     .cqi1
  83.         moveq.l #31,D3        ; D3 = sig number.
  84. .cqi2        move.w  D3,-(sp)
  85.         move.l  D3,D2        ; SetQVector(han, NULL, sig#, 0, 0)
  86.         move.l  A2,D0        ;         D0   D1    D2     D3  A0
  87.         moveq.l #0,D1
  88.         move.l  D1,D3
  89.         move.l  D1,A0
  90.         jsr     _lSetQVector
  91.         move.w  (sp)+,D3
  92.         dbf     D3,.cqi2
  93.  
  94. .cqi1        movem.l (sp)+,D2/D3/A2/A6
  95.         rts
  96.  
  97.  
  98.  
  99.         ;    _EXCEPT ,  Exception handler.
  100.         ;
  101.         ;entry:
  102.         ;    D0 = exceptions that occured
  103.         ;    A1 = Handle
  104.         ;
  105.         ;auto:
  106.         ;    A2    = Handle
  107.         ;    A4/A5    = Possible Global Base Registers
  108.         ;    D4    = Bit# count
  109.         ;    D6    = Exceptions that occured
  110.  
  111.  
  112. _except:
  113.         move.l    4,A6        ;A6 = Exec Base
  114.         move.l    D0,D6        ;D6 = Exception Bit Mask
  115.         movem.l    HAN_A4(A1),A4/A5;get global base register(s).
  116.         move.l    A1,A2        ;A2 = HANDLE BASE
  117.  
  118.         ;    Queue any exceptions which are interrupts.  Exceptions
  119.         ;    for interrupts which are queued are NOT reenabled until
  120.         ;    they are actually run.
  121.         ;
  122.         ;    Note that in the loop we must loop to .ex2 to decrement
  123.         ;    D4, which doesn't occur when we find a '1'.  The Z bit
  124.         ;    must be set when we loop to .ex2
  125.  
  126. .ex0        moveq.l    #31,D4        ;D4 = BIT NUMBER
  127. .ex1        btst.l    D4,D6        ; test bits
  128. .ex2        dbne    D4,.ex1     ; until found a '1'
  129.         beq     .ex10        ;or loop exhausted (D4 == -1)
  130.  
  131.         move.l    D4,D5        ;Calculate address of QINT.
  132.         asl.l    #5,D5        ;D5 = index * sizeof(QINT)
  133.         pea.l    HAN_QINT(A2)
  134.         add.l    (sp)+,D5        ;     + Base of QINT array
  135.         move.l    D5,A3        ;A3 = QINT address
  136.         tst.l    QINT_VECTOR(A3) ;Is this exception vectored?
  137.         beq     .ex2        ;no, somebody else owns it
  138.  
  139. .ex3        bclr.l    D4,D6        ;clear exception bit.
  140.         jsr     _LVOForbid(A6)  ;Important operation!
  141.         move.l    A3,A1        ;A1 = node
  142.         lea.l    HAN_LIST(A2),A0 ;A0 = List Base
  143.         move.b    #5,LN_TYPE(A1)  ;mark node as being queued
  144.         jsr     _LVOEnqueue(A6)
  145.         jsr     _LVOPermit(A6)  ;enable exceptions
  146.         clr.w    D7        ;Force Z cc set.
  147.         bra     .ex2        ;loop (force decrement/loop)
  148.  
  149.         ;    Call the handler.  The handler is allowed to trash
  150.         ;    everything except D6/A7.  Called with A2 = Handle,
  151.         ;    A6 = Exec Base
  152.  
  153. .ex10        tst.w    HAN_INHAN(A2)   ;no need to call handler?
  154.         bne     .ex11
  155.         bsr     _handler    ;call handler
  156. .ex11        move.l    D6,D0        ;D0 = exception mask
  157.         beq     .ex12        ;we processed all exceptions
  158.         move.l    HAN_EXCODE(A2),A0 ;somebody else owns some exceptions
  159.         move.l    HAN_EXDATA(A2),A1 ;restore exception data pointer
  160.         jmp     (A0)            ;call him with remaining exceptions.
  161. .ex12        rts
  162.  
  163.         ;entry:
  164.         ;    A2    = Handle
  165.         ;    A4/A5    = Possible Global Base Registers
  166.         ;    A6    = EXEC base
  167.         ;
  168.         ;auto:
  169.         ;    A2    = Handle;
  170.         ;    A3    = Qint
  171.         ;    A4/A5    = GBRs
  172.         ;    A6    = EXEC base
  173.         ;    D4    = savepri
  174.  
  175. _handler:
  176.         move.b    #1,HAN_INHAN(A2)
  177.         jsr     _LVOForbid(A6)
  178. .hloop        move.l    HAN_LIST+LH_HEAD(A2),A3
  179.         lea.l    HAN_LIST+LH_TAIL(A2),A0
  180.         cmp.l    A0,A3            ;List is empty
  181.         beq     .hbreak
  182.         move.b    HAN_PRI(A2),D4          ;Check priority of node
  183.         cmp.b    QINT_NODE+LN_PRI(A3),D4
  184.         bgt     .hbreak         ;savepri > qintpri
  185.         move.l    A3,A1            ;A1 = node to remove
  186.         jsr     _LVORemove(A6)
  187.         move.b    #0,QINT_NODE+LN_TYPE(A3)
  188.         move.b    QINT_NODE+LN_PRI(A3),HAN_PRI(A2)
  189.         jsr     _LVOPermit(A6)
  190.         move.l    QINT_ARG(A3),-(sp)
  191.         move.l    QINT_VECTOR(A3),A0
  192.         jsr     (A0)
  193.         move.l    4,A6
  194.         addq.l    #4,sp
  195.         move.b    D4,HAN_PRI(A2)
  196.         tst.l    QINT_VECTOR(A3)         ;Reenable the exception
  197.         beq     .h1            ;only if the vector still
  198.         move.l    QINT_SIGMASK(A3),D0     ;exists.
  199.         move.l    D0,D1
  200.         jsr     _LVOSetExcept(A6)
  201. .h1        jsr     _LVOForbid(A6)
  202.         bra     .hloop
  203.  
  204. .hbreak     moveq.l    #0,D2
  205.         move.b    D2,HAN_INHAN(A2)
  206.         jsr     _LVOPermit(A6)
  207.         move.l    D2,D0
  208.         move.l    D2,D1
  209.         jsr     _LVOSetExcept(A6)
  210.         rts
  211.  
  212.         ;    SetQVector()
  213.         ;
  214.         ;    D0 = handle (copy to A2)
  215.         ;    D1 = vector (copy to A3)
  216.         ;    D2 = signo
  217.         ;    D3 = arg    (copy to D5)
  218.         ;    A0 = pri
  219.         ;
  220.         ;    A2 = handle
  221.         ;    A3 = vector
  222.         ;    A4 = qint
  223.         ;    A5 = task
  224.         ;
  225.         ;    D2 = pri
  226.         ;    D3 = sigmask
  227.         ;    D4 = oldvector
  228.         ;    D5 = arg
  229.         ;    D6 =
  230.         ;    D7 =
  231.  
  232. _lSetQVector:
  233.         movem.l D2-D7/A2-A6,-(sp)
  234.         move.l  4,A6
  235.         move.l  D0,A2        ;   A2 = Handle
  236.         move.l  D1,A3        ;   A3 = Vector
  237.         move.l  D3,D5        ;   D5 =
  238.  
  239.         moveq.l #0,D3        ;   D3 = signal mask
  240.         bset.l  D2,D3        ;   D2 = signal
  241.         asl.l   #5,D2        ;   A4 = qint (han->QInt + signo)
  242.         add.l   #HAN_QINT,D2
  243.         add.l   A2,D2
  244.         move.l  D2,A4        ;   A4 = QINT
  245.         move.l  A0,D2        ;   D2 = priority
  246.         move.w  #0,A1        ;   A5 = task
  247.         jsr     _LVOFindTask(A6)
  248.         move.l  D0,A5
  249.  
  250.         jsr     _LVOForbid(A6)      ;   Forbid
  251.         move.l  QINT_VECTOR(A4),D4  ;   D4 = oldvector
  252.         move.l  A3,D0
  253.         bne     .sq100
  254.  
  255.         ;    If new vector is NULL, remove old vector if it exists.
  256.  
  257.         tst.l   D4
  258.         beq     .sqdone
  259.         moveq.l #0,D0
  260.         move.l  D3,D1
  261.         jsr     _LVOSetExcept(A6)
  262.         cmp.b   #5,QINT_NODE+LN_TYPE(A4)
  263.         bne     .sq1
  264.         move.l  A4,A1
  265.         jsr     _LVORemove(A6)
  266.         move.b  #0,QINT_NODE+LN_TYPE(A4)
  267. .sq1        sub.w   #1,HAN_INTS(A2)
  268.         bne     .sq2
  269.         jsr     _LVODisable(A6)
  270.         move.l  HAN_EXCODE(A2),TC_EXCEPTCODE(A5)
  271.         move.l  HAN_EXDATA(A2),TC_EXCEPTDATA(A5)
  272.         jsr     _LVOEnable(A6)
  273. .sq2        bra     .sqdone
  274.  
  275.         ;    If new vector not null, replace (possibly NULL) old vector
  276.  
  277. .sq100        tst.l   D4
  278.         bne     .sq150
  279.         add.w   #1,HAN_INTS(A2)     ; oldvector is null, setup task
  280.         cmp.w   #1,HAN_INTS(A2)
  281.         bne     .sq150
  282.         jsr     _LVODisable(A6)
  283.         move.l  TC_EXCEPTCODE(A5),HAN_EXCODE(A2)
  284.         move.l  TC_EXCEPTDATA(A5),HAN_EXDATA(A2)
  285.         move.l  #_except,TC_EXCEPTCODE(A5)
  286.         move.l  A2,TC_EXCEPTDATA(A5)
  287.         jsr     _LVOEnable(A6)
  288.  
  289. .sq150        move.l  D5,QINT_ARG(A4)
  290.         move.b  D2,QINT_NODE+LN_PRI(A4)
  291.         move.l  D3,QINT_SIGMASK(A4)
  292.         move.l  D3,D0
  293.         move.l  D3,D1
  294.         jsr     _LVOSetExcept(A6)
  295.         bra     .sqdone
  296.  
  297. .sqdone     move.l  A3,QINT_VECTOR(A4)
  298.         jsr     _LVOPermit(A6)
  299.         moveq.l #0,D0
  300.         move.l  D0,D1
  301.         jsr     _LVOSetExcept(A6)
  302.         move.l  D4,D0
  303.         movem.l (sp)+,D2-D7/A2-A6
  304.         rts
  305.  
  306.         ;    SetQPri
  307.         ;
  308.         ;    D0 = handle
  309.         ;    D1 = newpri
  310.         ;
  311.         ;    A2 = handle
  312.         ;    D2 = newpri
  313.         ;    D3 = oldpri
  314. _lSetQPri:
  315.         movem.l D2/D3/A2/A6,-(sp)
  316.         move.l  4,A6
  317.         move.l  D0,A2
  318.         move.l  D1,D2
  319.         jsr     _LVODisable(A6)
  320.         move.b  HAN_PRI(A2),D3
  321.         move.b  D2,HAN_PRI(A2)
  322.         jsr     _LVOEnable(A6)
  323.         cmp.b   D2,D3
  324.         ble     .sqpdone            ; D3 <= D2 (old <= new)
  325.         lea.l   HAN_LIST+LH_TAIL(A2),A0
  326.         cmp.l   HAN_LIST+LH_HEAD(A2),A0
  327.         beq     .sqpdone
  328.  
  329.         movem.l D4/A3,-(sp)
  330.         jsr     _handler            ;A2 = handle, A6 = execbase
  331.         movem.l (sp)+,D4/A3
  332. .sqpdone:
  333.         moveq.l #0,D0
  334.         move.b  D3,D0
  335.         movem.l (sp)+,D2/D3/A2/A6
  336.         rts
  337.  
  338.