home *** CD-ROM | disk | FTP | other *** search
/ The Fred Fish Collection 1.5 / ffcollection-1-5-1992-11.iso / ff_progs / prog_c / suplib.lzh / SUPLIB / SRC / MISC2.ASM < prev    next >
Assembly Source File  |  1991-08-16  |  10KB  |  449 lines

  1.  
  2.  
  3.         section DATA,DATA
  4.  
  5.         xref    _SysBase
  6.  
  7.         section CODE
  8.  
  9.         include "exec/types.i"
  10.         include "exec/ports.i"
  11.         include "exec/tasks.i"
  12.         include "exec/execbase.i"
  13.         include "exec/ables.i"
  14.         include "exec/memory.i"
  15.  
  16.  
  17.         ;   NOTE:   LockAddr/UnLockAddr referenced elsewhere in
  18.         ;        this library
  19.         ;   MISC2.ASM
  20.  
  21.         xref    _LVOPutMsg
  22.         xdef    _DoSyncMsg
  23.         xdef    _WaitMsg
  24.  
  25. _DoSyncMsg:    movem.l 4(sp),A0/A1
  26.         movem.l A2/A3/A6,-(sp)              ; A0=port, A1=msg
  27.         move.l    _SysBase,A6            ; A6=execbase
  28.  
  29.         sub.w    #MP_SIZE,sp            ; initialize reply port
  30.         move.b    #NT_MSGPORT,LN_TYPE(sp)
  31.         move.b    #PA_SIGNAL,MP_FLAGS(sp)
  32.         move.b    #4,MP_SIGBIT(sp)            ; EXEC semaphore signal
  33.         move.l    ThisTask(A6),MP_SIGTASK(sp)
  34.         lea    MP_MSGLIST(sp),A2
  35.         lea    MP_MSGLIST+4(sp),A3
  36.         move.l    A3,(A2)                     ; &tail -> head
  37.         move.l    #0,(A3)                     ; NULL  -> tail
  38.         move.l    A2,8(A2)                    ; &head -> tailpred
  39.  
  40.         move.l    sp,MN_REPLYPORT(A1)
  41.         move.l    A1,A2                ; save message
  42.         jsr    _LVOPutMsg(A6)              ; send the message
  43.  
  44.         move.l    A2,-(sp)
  45.         bsr    _WaitMsg
  46.         addq.l    #4,sp
  47.  
  48.         add.w    #MP_SIZE,sp
  49.         movem.l (sp)+,A2/A3/A6
  50.         rts
  51.  
  52.         xdef    _CheckMsg
  53.  
  54. _CheckMsg:    move.l    4(sp),A0
  55.         moveq.l #0,D0
  56.         cmp.b    #NT_MESSAGE,LN_TYPE(A0) ;NT_MESSAGE == not replied
  57.         beq    .lcm1
  58.         move.l    A0,D0
  59. .lcm1        rts
  60.  
  61.         xdef    _CheckPort
  62.  
  63. _CheckPort:    move.l    4(sp),A0
  64.         moveq.l #0,D0
  65.         move.l    MP_MSGLIST+LH_HEAD(A0),A0
  66.         tst.l    (A0)                    ;list empty?
  67.         beq    .lcp1
  68.         move.l    A0,D0            ;no, return first element
  69. .lcp1        rts
  70.  
  71.         xref    _LVOWait
  72.         xref    _LVORemove
  73.         xref    _LVODisable
  74.         xref    _LVOEnable
  75.  
  76.         xdef    _WaitMsg
  77.  
  78. _WaitMsg:    move.l    4(sp),A0
  79.         movem.l A2/A3/A6,-(sp)
  80.         move.l    A0,A2            ;A2 = message
  81.         move.l    MN_REPLYPORT(A0),A3     ;A3 = replyport
  82.         move.l    _SysBase,A6        ;A6 = execbase
  83. .wmloop     cmp.b    #NT_MESSAGE,LN_TYPE(A2) ;while msg not replied
  84.         bne    .wm1
  85.         move.b    MP_SIGBIT(A3),D1        ;Wait on port signal
  86.         moveq.l #0,D0
  87.         bset.l    D1,D0
  88.         jsr    _LVOWait(A6)
  89.         bra    .wmloop
  90. .wm1        jsr    _LVODisable(A6)         ;remove from port
  91.         move.l    A2,A1            ;A1 = message (A2)
  92.         jsr    _LVORemove(A6)
  93.         jsr    _LVOEnable(A6)
  94.         move.l    A2,D0            ;return message
  95.         movem.l (sp)+,A2/A3/A6
  96.         rts
  97.  
  98.         ;WILDCMP(wild:D0, name:D1)
  99.         ;
  100.         ;   Handles * and ?
  101.         ;
  102.         ;result:  D0, 0 = no match, 1 = match
  103.         ;
  104.         ;auto:
  105.         ;   D2    bi
  106.         ;   A2    wildcard string
  107.         ;   A3    name     string
  108.         ;   A4    back-array (of size MAXB * 2 * 4)
  109.  
  110. MAXB        EQU    8
  111.  
  112.         xdef    _WildCmp
  113.  
  114. _WildCmp:    movem.l 4(sp),D0/D1
  115.         movem.l D2/A2-A4,-(sp)
  116.         move.l    D0,A2
  117.         move.l    D1,A3
  118.         sub.l    #MAXB*2*8,sp
  119.         move.l    sp,A4
  120.  
  121.         moveq.l #0,D2
  122.  
  123. .wcloop     moveq.l #1,D0
  124.         move.b    (A2),D1
  125.         bne    .w1
  126.         tst.b    (A3)
  127.         beq    .wcdone
  128.  
  129. .w1        cmp.b    #'*',D1
  130.         bne    .w10
  131.         cmp.w    #MAXB,D2
  132.         bne    .w2
  133.         moveq.l #-1,D0        ; error
  134.         bra    .wcdone
  135. .w2        move.w    D2,D0        ; back[bi][0] = w  i.e. back+bi*8
  136.         asl.w    #3,D0        ; back[bi][1] = n
  137.         move.l    A2,0(A4,D0.w)
  138.         move.l    A3,4(A4,D0.w)
  139.         addq.w    #1,D2
  140.         addq.l    #1,A2
  141.         bra    .wcloop
  142.  
  143. .wgoback    subq.w    #1,D2
  144.         bmi    .w5
  145.         move.w    D2,D0
  146.         asl.w    #3,D0
  147.         move.l    4(A4,D0.w),A0
  148.         tst.b    (A0)
  149.         beq    .wgoback
  150. .w5        tst.w    D2
  151.         bmi    .wcret0
  152.         move.w    D2,D0
  153.         asl.w    #3,D0
  154.         move.l    0(A4,D0.w),A2
  155.         addq.l    #1,A2
  156.         add.l    #1,4(A4,D0.w)
  157.         move.l    4(A4,D0.w),A3
  158.         addq.l    #1,D2
  159.         bra    .wcloop
  160.  
  161. .w10        cmp.b    #'?',D1
  162.         bne    .w20
  163.         tst.b    (A3)
  164.         bne    .wcbreak
  165.         tst.w    D2
  166.         bne    .wgoback
  167.         bra    .wcret0
  168.  
  169. .w20        move.b    (A3),D0
  170.         cmp.b    #'A',D0
  171.         bcs    .w21
  172.         cmp.b    #'Z',D0
  173.         bhi    .w21
  174.         or.b    #$20,D0
  175. .w21        move.b    (A2),D1
  176.         cmp.b    #'A',D1
  177.         bcs    .w22
  178.         cmp.b    #'Z',D1
  179.         bhi    .w22
  180.         or.b    #$20,D1
  181. .w22        cmp.b    D0,D1
  182.         beq    .wcbreak
  183.         tst.w    D2
  184.         bne    .wgoback
  185.         bra    .wcret0
  186.  
  187. .wcbreak    tst.b    (A2)+
  188.         bne    .wcb1
  189.         subq.l    #1,A2
  190. .wcb1        tst.b    (A3)+
  191.         bne    .wcb2
  192.         subq.l    #1,A3
  193. .wcb2        bra    .wcloop
  194.  
  195. .wcret0     moveq.l #0,D0
  196. .wcdone     add.l    #MAXB*2*8,sp
  197.         movem.l (sp)+,D2/A2-A4
  198.         rts
  199.  
  200.         ;            LOCKS
  201.         ;
  202.         ;   {                LOCKADDR STRUCTURE
  203.         ;    ulong    Link;        dynamic linking of blocked requests
  204.         ;    ubyte    LockByte;   bset to here
  205.         ;    ubyte    Reserved;   reserved for future use (flags?)
  206.         ;                EXTENSIONS FOR TASKLOCK
  207.         ;    uword    Refs;        reference count same-task has-locked
  208.         ;    ulong    Task;        task address
  209.         ;   }
  210.         ;
  211.         ;   long var[3] = { 0, 0, 0 };
  212.         ;
  213.         ;   These routines work exactly like the lockaddr but maintain
  214.         ;   an additional reference count, allowing the same task to
  215.         ;   lock the same lock any number of times (the same number of
  216.         ;   unlocks are required to unlock the lock)
  217.         ;
  218.         ;   Only one lock is available per structure
  219.         ;
  220.         ;   TaskLock(&var[0]:A0)
  221.         ;   TaskUnlock(&var[0]:A0)
  222.  
  223. _lTaskLock:
  224.         move.l    _SysBase,A1    ; task address used for ident
  225.         move.l    ThisTask(A1),A1
  226.         bset.b    #0,4(A0)        ; try to get lock fast
  227.         beq    .tl10        ; beq success
  228.         cmp.l    8(A0),A1        ; failure, but is it the same task?
  229.         beq    .tl11        ; yes, success
  230.         movem.l A0/A1,-(sp)     ; failure, different task, block.
  231.         moveq.l #0,D0        ; D0 = bit#, A0 = lock ptr
  232.         bsr    LA0        ; get lock the hard way
  233.         movem.l (sp)+,A0/A1
  234. .tl10        move.l    A1,8(A0)        ; success, store owner
  235. .tl11        add.w    #1,6(A0)        ; success, bump ref count
  236.         rts
  237.  
  238. ;;BREAKUP   lockaddr.asm
  239.  
  240.         ;   long var[2] = { 0, 0 };
  241.         ;
  242.         ;   These routines provide fast exclusive
  243.         ;   locks.  Up to 8 independant locks may be used for
  244.         ;   each 4 byte address.
  245.         ;
  246.         ;   LockAddr(&var[0]:A0)
  247.         ;   LockAddrB(bit:D0, &var[0]:A0)
  248.         ;   UnlockAddr(&var[0]:A0)
  249.         ;   UnlockAddrB(bit:D0, &var[0]:A0)
  250.         ;   TryLockAddr(&var[0]:A0)
  251.         ;   TryLockAddrB(bit:D0, &var[0]:A0)
  252.  
  253.         xref    _LVOWait
  254.         xref    _LVOForbid
  255.         xref    _LVOPermit
  256.  
  257.         xdef    _LockAddr
  258.         xdef    _LockAddrB
  259.         xdef    _TryLockAddr
  260.         xdef    _TryLockAddrB
  261.            IFD LATTICE
  262.         xdef    @LockAddr
  263.         xdef    @LockAddrB
  264.         xdef    @TryLockAddr
  265.         xdef    @TryLockAddrB
  266.            ENDC
  267.  
  268. _TryLockAddrB:    movem.l 4(sp),D0/A0
  269.         bra    TLA0
  270. _TryLockAddr:
  271.         move.l    4(sp),A0
  272.  
  273.            IFD LATTICE
  274. @TryLockAddr:
  275.            ENDC
  276.         moveq.l #0,D0
  277.            IFD LATTICE
  278. @TryLockAddrB:
  279.            ENDC
  280.  
  281. TLA0:        bset.b    D0,4(A0)                ; attempt to gain lock
  282.         bne    .tla10            ; failure
  283.         moveq.l #1,D0
  284.         rts                ; success, return 1
  285. .tla10        moveq.l #-1,D0            ; failure, return -1
  286.         rts
  287.  
  288.  
  289.  
  290. _LockAddrB:    movem.l 4(sp),D0/A0             ; bit: D0    lock: A0
  291.         bra    LA0
  292. _LockAddr:                    ; bit: 0     lock: A0
  293.         move.l    4(sp),A0
  294.  
  295.         ;    MAIN LOCK CODE
  296.  
  297.            IFD LATTICE
  298. @LockAddr:
  299.            ENDC
  300.         moveq.l #0,D0
  301.            IFD LATTICE
  302. @LockAddrB:
  303.            ENDC
  304. LA0:        bset.b    D0,4(A0)                ; attempt to gain lock
  305.         bne    .la10            ; failure
  306.         rts                ; success, done, rts (FAST)
  307.  
  308. .la10        movem.l A2/A6,-(sp)             ; failure (SLOW) (BLOCK)
  309.         move.l    _SysBase,A6        ; A6 = SYSBase
  310.         FORBID
  311.         bset.b    D0,4(A0)                ; try again after FORBID
  312.         beq    .la20            ; got it!
  313.  
  314.         ;   Put linked list structure on stack
  315.  
  316.         move.w    D0,-(sp)                ; bit#    12(sp)
  317.         move.l    ThisTask(A6),-(sp)      ; task#    8(sp)
  318.         move.l    A0,-(sp)                ; &var     4(sp)
  319.         move.l    (A0),-(sp)              ; Next      (sp)
  320.         move.l    sp,(A0)                 ; (put at head of list)
  321.  
  322.         ;   Loop Wait/re-attempt lock
  323.  
  324. .la15        moveq.l #$10,D0         ; wait (semaphore signal)
  325.         jsr    _LVOWait(A6)
  326.  
  327.         move.w    12(sp),D0               ; try for lock
  328.         move.l    4(sp),A0
  329.         bset.b    D0,4(A0)
  330.         bne    .la15            ; loop until get it
  331.  
  332. .la16        cmp.l    (A0),sp                 ; unlink, find our node!
  333.         beq    .la18
  334.         move.l    (A0),A0
  335.         bra    .la16
  336. .la18        move.l    (sp),(A0)
  337.         add.w    #14,sp
  338. .la20
  339.         PERMIT
  340.         movem.l (sp)+,A2/A6
  341.         rts
  342.  
  343. ;;BREAKUP   unlockaddr.asm
  344.  
  345.         ;   TaskUnlock() works on an expanded lock (see TaskLock() above)
  346.         ;   while UnlockAddr[B] works on a basic lock.
  347.  
  348.         xdef    _TaskUnlock
  349.  
  350. _TaskUnlock:    move.l    4(sp),A0
  351.  
  352.         sub.w    #1,6(A0)    ; decrement reference count
  353.         bne    .tu10        ; non-zero, do not release lock yet
  354.         moveq.l #0,D0        ; D0 = 0 (needed for ULW)
  355.         move.l    D0,8(A0)    ; clear the owner field
  356.  
  357.                     ; this repeats some of the unlock code
  358.         bclr.b    #0,4(A0)    ; clear the lock
  359.         move.l    (A0),D1     ; Anybody waiting to get the lock?
  360.         bne    ULW        ; yes, branch to unlock code
  361. .tu10        rts            ; no, return immediately.
  362.  
  363.         xref    _LVOSignal
  364.         xref    _LVOForbid
  365.         xref    _LVOPermit
  366.  
  367.         xdef    _UnlockAddr
  368.         xdef    _UnlockAddrB
  369.            IFD LATTICE
  370.         xdef    @UnlockAddr
  371.         xdef    @UnlockAddrB
  372.            ENDC
  373.  
  374. _UnlockAddrB:    movem.l 4(sp),D0/A0
  375.         bra.s    UL0
  376. _UnlockAddr:    move.l    4(sp),A0
  377.            IFD LATTICE
  378. @UnlockAddr:
  379.            ENDC
  380.         moveq.l #0,D0
  381.            IFD LATTICE
  382. @UnlockAddrB:
  383.            ENDC
  384.  
  385. UL0:        bclr.b    D0,4(A0)                ; clear lock bit
  386.         move.l    (A0),D1                 ; anybody waiting?
  387.         beq    .ulrts            ; no, rts
  388. ULW:
  389.         movem.l D2/A2/A6,-(sp)          ; yes, wake 'm all up
  390.         move.b    D0,D2            ; D2 = bit#
  391.         move.l    _SysBase,A6        ; A6 = SYSBase
  392.         FORBID
  393.  
  394.         move.l    (A0),D1                 ; get pointer again after FORBID
  395.         beq    .ul20            ; no, rts (close a window)
  396.  
  397. .ul10        move.l    D1,A2            ; A2 = node
  398.         cmp.b    13(A2),D2               ; waiting on our bit #?
  399.         bne    .ul18            ; no
  400.         move.l    8(A2),A1                ; yes, signal the node
  401.         moveq.l #$10,D0
  402.         jsr    _LVOSignal(A6)          ; signal EVERYONE waiting
  403. .ul18        move.l    (A2),D1                 ; next
  404.         bne    .ul10
  405.  
  406. .ul20
  407.         PERMIT
  408.         movem.l (sp)+,D2/A2/A6
  409. .ulrts        rts
  410.  
  411.  
  412.         ;   FindName2(list:D0, name:A0)
  413.         ;
  414.         ;   Search the node list as in FindName(), but also ignore
  415.         ;   NULL ln_name entries, which FindName() does not do.  This
  416.         ;   routine will also return NULL if given an uninitialized
  417.         ;   list header (completely zero'd).  Finally, it will not
  418.         ;   bother to do a string compare if the two pointers are
  419.         ;   the same.
  420.  
  421.         xdef    _FindName2
  422.  
  423. _FindName2:    movem.l 4(sp),D0/A0
  424.         movem.l A2/A3,-(sp)
  425.         move.l    D0,A1
  426.         tst.l    (A1)                        ; uninitialized list header
  427.         beq    .fn2fail
  428. .fn2loop    move.l    (A1),A1                     ; get first/next node
  429.         tst.l    (A1)                        ; end of list?
  430.         beq    .fn2fail
  431.         move.l    LN_NAME(A1),D0              ; name
  432.         beq    .fn2loop            ; NULL, skip
  433.         cmp.l    D0,A0                ; pointers are the same!
  434.         beq    .fn2succ            ;  don't bother w/cmp.
  435.         move.l    D0,A2
  436.         move.l    A0,A3
  437. .fn2l2        cmpm.b    (A2)+,(A3)+
  438.         bne    .fn2loop
  439.         tst.b    -1(A2)
  440.         bne    .fn2l2
  441. .fn2succ    move.l    A1,D0
  442.         movem.l (sp)+,A2/A3
  443.         rts
  444. .fn2fail    moveq.l #0,D0
  445.         movem.l (sp)+,A2/A3
  446.         rts
  447.  
  448.         END
  449.