home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 177.lha / DRes_v1.3 / src / misc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1988-04-28  |  8.0 KB  |  368 lines

  1.  
  2. /*
  3.  *  MISC.C
  4.  *
  5.  *  General Stuff... mostly in assembly.
  6.  */
  7.  
  8. #include <local/typedefs.h>
  9.  
  10. typedef struct {
  11.     NODE     ml_Node;
  12.     uword    ml_NumEntries;
  13.     MEMENTRY ml_ME[2];
  14. } MYMEMLIST;
  15.  
  16. APTR
  17. lGetTaskData(name, bytes)
  18. char *name;
  19. long bytes;
  20. {
  21.     extern EXECBASE *SysBase;
  22.     extern void *FindName2();
  23.     register LIST *list;
  24.     register MEMLIST *ml;
  25.  
  26.     list = &SysBase->ThisTask->tc_MemEntry;
  27.     if (ml = FindName2(list, name))
  28.     return(ml->ml_ME[0].me_Un.meu_Addr);
  29.     if (!list->lh_Head)
  30.     NewList(list);
  31.     {
  32.     MYMEMLIST Ml;
  33.  
  34.     Ml.ml_NumEntries = 2;
  35.     Ml.ml_ME[0].me_Un.meu_Reqs = MEMF_PUBLIC|MEMF_CLEAR;
  36.     Ml.ml_ME[0].me_Length = bytes;
  37.     Ml.ml_ME[1].me_Un.meu_Reqs = MEMF_PUBLIC;
  38.     Ml.ml_ME[1].me_Length = strlen(name)+1;
  39.     if (ml = AllocEntry(&Ml)) {
  40.         ml->ml_Node.ln_Name = (char *)ml->ml_ME[1].me_Un.meu_Addr;
  41.         strcpy(ml->ml_Node.ln_Name, name);
  42.         AddHead(list, ml);
  43.         return(ml->ml_ME[0].me_Un.meu_Addr);
  44.     }
  45.     }
  46.     return(NULL);
  47. }
  48.  
  49. lFreeTaskData(name)
  50. char *name;
  51. {
  52.     extern EXECBASE *SysBase;
  53.     extern void *FindName2();
  54.     register MEMLIST *ml;
  55.  
  56.     if (ml = FindName2(&SysBase->ThisTask->tc_MemEntry, name)) {
  57.     Remove(ml);
  58.     FreeEntry(ml);
  59.     return(1);
  60.     }
  61.     return(0);
  62. }
  63.  
  64.  
  65. #asm
  66.  
  67.  
  68.         include "exec/types.i"
  69.         include "exec/ports.i"
  70.         include "exec/tasks.i"
  71.         include "exec/execbase.i"
  72.         include "exec/ables.i"
  73.         include "exec/memory.i"
  74.  
  75.         ;   NOTE:   LockAddr/UnLockAddr referenced elsewhere in
  76.         ;        this library
  77.  
  78.         ;   MISC.ASM
  79.  
  80.         public    _lWildCmp    ; Wildcard compare
  81.         public    _lWaitMsg    ; Wait for a message to be replied
  82.         public    _lCheckMsg    ; Check if message has been returned
  83.         public    _lCheckPort    ; Check if message pending on port
  84.         public    _lDoSyncMsg    ; Put and Wait for a message
  85.         public    _lLockAddr
  86.         public    _lLockAddrB
  87.         public    _lUnLockAddr
  88.         public    _lUnLockAddrB
  89.         public    _lFindName2
  90.  
  91.         public    _LVOWait
  92.         public    _LVORemove
  93.         public    _LVODisable
  94.         public    _LVOEnable
  95.         public    _LVOFindTask
  96.         public    _LVOSignal
  97.         public    _LVOForbid
  98.         public    _LVOPermit
  99.         public    _LVOPutMsg
  100.  
  101.  
  102. _lDoSyncMsg:    movem.l A2/A3/A6,-(sp)              ; A0=port, A1=msg
  103.         move.l    4,A6                ; A6=execbase
  104.  
  105.         sub.w    #MP_SIZE,sp            ; initialize reply port
  106.         move.b    #NT_MSGPORT,LN_TYPE(sp)
  107.         move.b    #PA_SIGNAL,MP_FLAGS(sp)
  108.         move.b    #4,MP_SIGBIT(sp)            ; EXEC semaphore signal
  109.         move.l    ThisTask(A6),MP_SIGTASK(sp)
  110.         lea    MP_MSGLIST(sp),A2
  111.         lea    MP_MSGLIST+4(sp),A3
  112.         move.l    A3,(A2)                     ; &tail -> head
  113.         move.l    #0,(A3)                     ; NULL  -> tail
  114.         move.l    A2,8(A2)                    ; &head -> tailpred
  115.  
  116.         move.l    sp,MN_REPLYPORT(A1)
  117.         move.l    A1,A2                ; save message
  118.         jsr    _LVOPutMsg(A6)              ; send the message
  119.         move.l    A2,A0
  120.         bsr    _lWaitMsg            ; wait for reply
  121.  
  122.         add.w    #MP_SIZE,sp
  123.         movem.l (sp)+,A2/A3/A6
  124.         rts
  125.  
  126. _lCheckMsg:    moveq.l #0,D0
  127.         cmp.b    #NT_MESSAGE,LN_TYPE(A0) ;NT_MESSAGE == not replied
  128.         beq    .lcm1
  129.         move.l    A0,D0
  130. .lcm1        rts
  131.  
  132. _lCheckPort:    moveq.l #0,D0
  133.         move.l    MP_MSGLIST+LH_HEAD(A0),A0
  134.         tst.l    (A0)                    ;list empty?
  135.         beq    .lcp1
  136.         move.l    A0,D0            ;no, return first element
  137. .lcp1        rts
  138.  
  139. _lWaitMsg:                    ;A0 = message to wait for
  140.         movem.l A2/A3/A6,-(sp)
  141.         move.l    A0,A2            ;A2 = message
  142.         move.l    MN_REPLYPORT(A0),A3     ;A3 = replyport
  143.         move.l    4,A6            ;A6 = execbase
  144. .wmloop     cmp.b    #NT_MESSAGE,LN_TYPE(A2) ;while msg not replied
  145.         bne    .wm1
  146.         move.b    MP_SIGBIT(A3),D1        ;Wait on port signal
  147.         moveq.l #0,D0
  148.         bset.l    D1,D0
  149.         jsr    _LVOWait(A6)
  150.         bra    .wmloop
  151. .wm1        jsr    _LVODisable(A6)         ;remove from port
  152.         move.l    A2,A1            ;A1 = message (A2)
  153.         jsr    _LVORemove(A6)
  154.         jsr    _LVOEnable(A6)
  155.         move.l    A2,D0            ;return message
  156.         movem.l (sp)+,A2/A3/A6
  157.         rts
  158.  
  159.  
  160.         ;WILDCMP(wild:D0, name:D1)
  161.         ;
  162.         ;   Handles * and ?
  163.         ;
  164.         ;result:  D0, 0 = no match, 1 = match
  165.         ;
  166.         ;auto:
  167.         ;   D2    bi
  168.         ;   A2    wildcard string
  169.         ;   A3    name     string
  170.         ;   A4    back-array (of size MAXB * 2 * 4)
  171.  
  172.  
  173. MAXB        EQU    8
  174.  
  175. _lWildCmp:    movem.l D2/A2-A4,-(sp)
  176.         move.l    D0,A2
  177.         move.l    D1,A3
  178.         sub.l    #MAXB*2*8,sp
  179.         move.l    sp,A4
  180.  
  181.         moveq.l #0,D2
  182.  
  183. .wcloop     moveq.l #1,D0
  184.         move.b    (A2),D1
  185.         bne    .w1
  186.         tst.b    (A3)
  187.         beq    .wcdone
  188.  
  189. .w1        cmp.b    #'*',D1
  190.         bne    .w10
  191.         cmp.w    #MAXB,D2
  192.         bne    .w2
  193.         moveq.l #-1,D0        ; error
  194.         bra    .wcdone
  195. .w2        move.w    D2,D0        ; back[bi][0] = w  i.e. back+bi*8
  196.         asl.w    #3,D0        ; back[bi][1] = n
  197.         move.l    A2,(A4,D0.w)
  198.         move.l    A3,4(A4,D0.w)
  199.         addq.w    #1,D2
  200.         addq.l    #1,A2
  201.         bra    .wcloop
  202.  
  203. .wgoback    subq.w    #1,D2
  204.         bmi    .w5
  205.         move.w    D2,D0
  206.         asl.w    #3,D0
  207.         move.l    4(A4,D0.w),A0
  208.         tst.b    (A0)
  209.         beq    .wgoback
  210. .w5        tst.w    D2
  211.         bmi    .wcret0
  212.         move.w    D2,D0
  213.         asl.w    #3,D0
  214.         move.l    (A4,D0.w),A2
  215.         addq.l    #1,A2
  216.         add.l    #1,4(A4,D0.w)
  217.         move.l    4(A4,D0.w),A3
  218.         addq.l    #1,D2
  219.         bra    .wcloop
  220.  
  221. .w10        cmp.b    #'?',D1
  222.         bne    .w20
  223.         tst.b    (A3)
  224.         bne    .wcbreak
  225.         tst.w    D2
  226.         bne    .wgoback
  227.         bra    .wcret0
  228.  
  229. .w20        move.b    (A3),D0
  230.         cmp.b    #'A',D0
  231.         blo    .w21
  232.         cmp.b    #'Z',D0
  233.         bhi    .w21
  234.         or.b    #$20,D0
  235. .w21        move.b    (A2),D1
  236.         cmp.b    #'A',D1
  237.         blo    .w22
  238.         cmp.b    #'Z',D1
  239.         bhi    .w22
  240.         or.b    #$20,D1
  241. .w22        cmp.b    D0,D1
  242.         beq    .wcbreak
  243.         tst.w    D2
  244.         bne    .wgoback
  245.         bra    .wcret0
  246.  
  247. .wcbreak    tst.b    (A2)+
  248.         bne    .wcb1
  249.         subq.l    #1,A2
  250. .wcb1        tst.b    (A3)+
  251.         bne    .wcb2
  252.         subq.l    #1,A3
  253. .wcb2        bra    .wcloop
  254.  
  255. .wcret0     moveq.l #0,D0
  256. .wcdone     add.l    #MAXB*2*8,sp
  257.         movem.l (sp)+,D2/A2-A4
  258.         rts
  259.  
  260.         ;   long var[2] = { 0, 0 };
  261.         ;
  262.         ;   These routines provide fast exclusive
  263.         ;   locks.  Up to 8 independant locks may be used for
  264.         ;   each 4 byte address.
  265.         ;
  266.         ;   LockAddr(&var[0]:A0)
  267.         ;   LockAddrB(bit:D0, &var[0]:A0)
  268.         ;   UnLockAddr(&var[0]:A0)
  269.         ;   UnLockAddrB(bit:D0, &var[0]:A0)
  270.  
  271.  
  272. _lLockAddr:    moveq.l #0,D0            ; bit 0
  273. _lLockAddrB:    bset.b    D0,4(A0)                ; attempt to gain lock
  274.         bne    .la10
  275.         rts                ; was clear, so got it
  276. .la10        movem.l A2/A6,-(sp)             ; else failed,
  277.         move.l    4,A6            ; A6 = SYSBase
  278.         FORBID
  279.         bset.b    D0,4(A0)                ; try again
  280.         beq    .la20            ; got it!
  281.  
  282.         move.w    D0,-(sp)                ; bit#    12(sp)
  283.         move.l    ThisTask(A6),-(sp)      ; task#    8(sp)
  284.         move.l    A0,-(sp)                ; &var     4(sp)
  285.         move.l    (A0),-(sp)              ; Next      (sp)
  286.         move.l    sp,(A0)                 ; (put at head of list)
  287. .la15        moveq.l #$10,D0         ; wait (semaphore signal)
  288.         jsr    _LVOWait(A6)
  289.  
  290.         move.w    12(sp),D0               ; try for lock
  291.         move.l    4(sp),A0
  292.         bset.b    D0,4(A0)
  293.         bne    .la15            ; loop until get it
  294.  
  295. .la16        cmp.l    (A0),sp                 ; unlink, find our node!
  296.         beq    .la18
  297.         move.l    (A0),A0
  298.         bra    .la16
  299. .la18        move.l    (sp),(A0)
  300.         add.w    #14,sp
  301. .la20
  302.         PERMIT
  303.         movem.l (sp)+,A2/A6
  304.         rts
  305.  
  306. _lUnLockAddr:    moveq.l #0,D0            ; bit 0
  307. _lUnLockAddrB:    bclr.b    D0,4(A0)                ; clear lock bit
  308.         move.l    (A0),D1                 ; anybody waiting?
  309.         beq    .ulrts            ; no, rts
  310.  
  311.         movem.l D2/A2/A6,-(sp)          ; yes, wake 'm all up
  312.         move.b    D0,D2            ; D2 = bit#
  313.         move.l    4,A6            ; A6 = SYSBase
  314.         FORBID
  315.  
  316.         move.l    (A0),D1                 ; get pointer again after FORBID
  317.         beq    .ul20            ; no, rts (close a window)
  318.  
  319. .ul10        move.l    D1,A2            ; A2 = node
  320.         cmp.b    13(A2),D2               ; waiting on our bit #?
  321.         bne    .ul18            ; no
  322.         move.l    8(A2),A1                ; yes, signal the node
  323.         moveq.l #$10,D0
  324.         jsr    _LVOSignal(A6)          ; signal EVERYONE waiting
  325. .ul18        move.l    (A2),D1                 ; next
  326.         bne    .ul10
  327.  
  328. .ul20
  329.         PERMIT
  330.         movem.l (sp)+,D2/A2/A6
  331. .ulrts        rts
  332.  
  333.         ;   FindName2(list:D0, name:A0)
  334.         ;
  335.         ;   Search the node list as in FindName(), but also ignore
  336.         ;   NULL ln_name entries, which FindName() does not do.  This
  337.         ;   routine will also return NULL if given an uninitialized
  338.         ;   list header (completely zero'd).  Finally, it will not
  339.         ;   bother to do a string compare if the two pointers are
  340.         ;   the same.
  341.  
  342. _lFindName2:    movem.l A2/A3,-(sp)
  343.         move.l    D0,A1
  344.         tst.l    (A1)                        ; uninitialized list header
  345.         beq    .fn2fail
  346. .fn2loop    move.l    (A1),A1                     ; get first/next node
  347.         tst.l    (A1)                        ; end of list?
  348.         beq    .fn2fail
  349.         move.l    LN_NAME(A1),D0              ; name
  350.         beq    .fn2loop            ; NULL, skip
  351.         cmp.l    D0,A0                ; pointers are the same!
  352.         beq    .fn2succ            ;  don't bother w/cmp.
  353.         move.l    D0,A2
  354.         move.l    A0,A3
  355. .fn2l2        cmpm.b    (A2)+,(A3)+
  356.         bne    .fn2loop
  357.         tst.b    -1(A2)
  358.         bne    .fn2l2
  359. .fn2succ    move.l    A1,D0
  360.         movem.l (sp)+,A2/A3
  361.         rts
  362. .fn2fail    moveq.l #0,D0
  363.         movem.l (sp)+,A2/A3
  364.         rts
  365.  
  366. #endasm
  367.  
  368.