home *** CD-ROM | disk | FTP | other *** search
-
- /*
- * MISC.C
- *
- * General Stuff... mostly in assembly.
- */
-
- #include <local/typedefs.h>
-
- typedef struct {
- NODE ml_Node;
- uword ml_NumEntries;
- MEMENTRY ml_ME[2];
- } MYMEMLIST;
-
- APTR
- lGetTaskData(name, bytes)
- char *name;
- long bytes;
- {
- extern EXECBASE *SysBase;
- extern void *FindName2();
- register LIST *list;
- register MEMLIST *ml;
-
- list = &SysBase->ThisTask->tc_MemEntry;
- if (ml = FindName2(list, name))
- return(ml->ml_ME[0].me_Un.meu_Addr);
- if (!list->lh_Head)
- NewList(list);
- {
- MYMEMLIST Ml;
-
- Ml.ml_NumEntries = 2;
- Ml.ml_ME[0].me_Un.meu_Reqs = MEMF_PUBLIC|MEMF_CLEAR;
- Ml.ml_ME[0].me_Length = bytes;
- Ml.ml_ME[1].me_Un.meu_Reqs = MEMF_PUBLIC;
- Ml.ml_ME[1].me_Length = strlen(name)+1;
- if (ml = AllocEntry(&Ml)) {
- ml->ml_Node.ln_Name = (char *)ml->ml_ME[1].me_Un.meu_Addr;
- strcpy(ml->ml_Node.ln_Name, name);
- AddHead(list, ml);
- return(ml->ml_ME[0].me_Un.meu_Addr);
- }
- }
- return(NULL);
- }
-
- lFreeTaskData(name)
- char *name;
- {
- extern EXECBASE *SysBase;
- extern void *FindName2();
- register MEMLIST *ml;
-
- if (ml = FindName2(&SysBase->ThisTask->tc_MemEntry, name)) {
- Remove(ml);
- FreeEntry(ml);
- return(1);
- }
- return(0);
- }
-
-
- #asm
-
-
- include "exec/types.i"
- include "exec/ports.i"
- include "exec/tasks.i"
- include "exec/execbase.i"
- include "exec/ables.i"
- include "exec/memory.i"
-
- ; NOTE: LockAddr/UnLockAddr referenced elsewhere in
- ; this library
-
- ; MISC.ASM
-
- public _lWildCmp ; Wildcard compare
- public _lWaitMsg ; Wait for a message to be replied
- public _lCheckMsg ; Check if message has been returned
- public _lCheckPort ; Check if message pending on port
- public _lDoSyncMsg ; Put and Wait for a message
- public _lLockAddr
- public _lLockAddrB
- public _lUnLockAddr
- public _lUnLockAddrB
- public _lFindName2
-
- public _LVOWait
- public _LVORemove
- public _LVODisable
- public _LVOEnable
- public _LVOFindTask
- public _LVOSignal
- public _LVOForbid
- public _LVOPermit
- public _LVOPutMsg
-
-
- _lDoSyncMsg: movem.l A2/A3/A6,-(sp) ; A0=port, A1=msg
- move.l 4,A6 ; A6=execbase
-
- sub.w #MP_SIZE,sp ; initialize reply port
- move.b #NT_MSGPORT,LN_TYPE(sp)
- move.b #PA_SIGNAL,MP_FLAGS(sp)
- move.b #4,MP_SIGBIT(sp) ; EXEC semaphore signal
- move.l ThisTask(A6),MP_SIGTASK(sp)
- lea MP_MSGLIST(sp),A2
- lea MP_MSGLIST+4(sp),A3
- move.l A3,(A2) ; &tail -> head
- move.l #0,(A3) ; NULL -> tail
- move.l A2,8(A2) ; &head -> tailpred
-
- move.l sp,MN_REPLYPORT(A1)
- move.l A1,A2 ; save message
- jsr _LVOPutMsg(A6) ; send the message
- move.l A2,A0
- bsr _lWaitMsg ; wait for reply
-
- add.w #MP_SIZE,sp
- movem.l (sp)+,A2/A3/A6
- rts
-
- _lCheckMsg: moveq.l #0,D0
- cmp.b #NT_MESSAGE,LN_TYPE(A0) ;NT_MESSAGE == not replied
- beq .lcm1
- move.l A0,D0
- .lcm1 rts
-
- _lCheckPort: moveq.l #0,D0
- move.l MP_MSGLIST+LH_HEAD(A0),A0
- tst.l (A0) ;list empty?
- beq .lcp1
- move.l A0,D0 ;no, return first element
- .lcp1 rts
-
- _lWaitMsg: ;A0 = message to wait for
- movem.l A2/A3/A6,-(sp)
- move.l A0,A2 ;A2 = message
- move.l MN_REPLYPORT(A0),A3 ;A3 = replyport
- move.l 4,A6 ;A6 = execbase
- .wmloop cmp.b #NT_MESSAGE,LN_TYPE(A2) ;while msg not replied
- bne .wm1
- move.b MP_SIGBIT(A3),D1 ;Wait on port signal
- moveq.l #0,D0
- bset.l D1,D0
- jsr _LVOWait(A6)
- bra .wmloop
- .wm1 jsr _LVODisable(A6) ;remove from port
- move.l A2,A1 ;A1 = message (A2)
- jsr _LVORemove(A6)
- jsr _LVOEnable(A6)
- move.l A2,D0 ;return message
- movem.l (sp)+,A2/A3/A6
- rts
-
-
- ;WILDCMP(wild:D0, name:D1)
- ;
- ; Handles * and ?
- ;
- ;result: D0, 0 = no match, 1 = match
- ;
- ;auto:
- ; D2 bi
- ; A2 wildcard string
- ; A3 name string
- ; A4 back-array (of size MAXB * 2 * 4)
-
-
- MAXB EQU 8
-
- _lWildCmp: movem.l D2/A2-A4,-(sp)
- move.l D0,A2
- move.l D1,A3
- sub.l #MAXB*2*8,sp
- move.l sp,A4
-
- moveq.l #0,D2
-
- .wcloop moveq.l #1,D0
- move.b (A2),D1
- bne .w1
- tst.b (A3)
- beq .wcdone
-
- .w1 cmp.b #'*',D1
- bne .w10
- cmp.w #MAXB,D2
- bne .w2
- moveq.l #-1,D0 ; error
- bra .wcdone
- .w2 move.w D2,D0 ; back[bi][0] = w i.e. back+bi*8
- asl.w #3,D0 ; back[bi][1] = n
- move.l A2,(A4,D0.w)
- move.l A3,4(A4,D0.w)
- addq.w #1,D2
- addq.l #1,A2
- bra .wcloop
-
- .wgoback subq.w #1,D2
- bmi .w5
- move.w D2,D0
- asl.w #3,D0
- move.l 4(A4,D0.w),A0
- tst.b (A0)
- beq .wgoback
- .w5 tst.w D2
- bmi .wcret0
- move.w D2,D0
- asl.w #3,D0
- move.l (A4,D0.w),A2
- addq.l #1,A2
- add.l #1,4(A4,D0.w)
- move.l 4(A4,D0.w),A3
- addq.l #1,D2
- bra .wcloop
-
- .w10 cmp.b #'?',D1
- bne .w20
- tst.b (A3)
- bne .wcbreak
- tst.w D2
- bne .wgoback
- bra .wcret0
-
- .w20 move.b (A3),D0
- cmp.b #'A',D0
- blo .w21
- cmp.b #'Z',D0
- bhi .w21
- or.b #$20,D0
- .w21 move.b (A2),D1
- cmp.b #'A',D1
- blo .w22
- cmp.b #'Z',D1
- bhi .w22
- or.b #$20,D1
- .w22 cmp.b D0,D1
- beq .wcbreak
- tst.w D2
- bne .wgoback
- bra .wcret0
-
- .wcbreak tst.b (A2)+
- bne .wcb1
- subq.l #1,A2
- .wcb1 tst.b (A3)+
- bne .wcb2
- subq.l #1,A3
- .wcb2 bra .wcloop
-
- .wcret0 moveq.l #0,D0
- .wcdone add.l #MAXB*2*8,sp
- movem.l (sp)+,D2/A2-A4
- rts
-
- ; long var[2] = { 0, 0 };
- ;
- ; These routines provide fast exclusive
- ; locks. Up to 8 independant locks may be used for
- ; each 4 byte address.
- ;
- ; LockAddr(&var[0]:A0)
- ; LockAddrB(bit:D0, &var[0]:A0)
- ; UnLockAddr(&var[0]:A0)
- ; UnLockAddrB(bit:D0, &var[0]:A0)
-
-
- _lLockAddr: moveq.l #0,D0 ; bit 0
- _lLockAddrB: bset.b D0,4(A0) ; attempt to gain lock
- bne .la10
- rts ; was clear, so got it
- .la10 movem.l A2/A6,-(sp) ; else failed,
- move.l 4,A6 ; A6 = SYSBase
- FORBID
- bset.b D0,4(A0) ; try again
- beq .la20 ; got it!
-
- move.w D0,-(sp) ; bit# 12(sp)
- move.l ThisTask(A6),-(sp) ; task# 8(sp)
- move.l A0,-(sp) ; &var 4(sp)
- move.l (A0),-(sp) ; Next (sp)
- move.l sp,(A0) ; (put at head of list)
- .la15 moveq.l #$10,D0 ; wait (semaphore signal)
- jsr _LVOWait(A6)
-
- move.w 12(sp),D0 ; try for lock
- move.l 4(sp),A0
- bset.b D0,4(A0)
- bne .la15 ; loop until get it
-
- .la16 cmp.l (A0),sp ; unlink, find our node!
- beq .la18
- move.l (A0),A0
- bra .la16
- .la18 move.l (sp),(A0)
- add.w #14,sp
- .la20
- PERMIT
- movem.l (sp)+,A2/A6
- rts
-
- _lUnLockAddr: moveq.l #0,D0 ; bit 0
- _lUnLockAddrB: bclr.b D0,4(A0) ; clear lock bit
- move.l (A0),D1 ; anybody waiting?
- beq .ulrts ; no, rts
-
- movem.l D2/A2/A6,-(sp) ; yes, wake 'm all up
- move.b D0,D2 ; D2 = bit#
- move.l 4,A6 ; A6 = SYSBase
- FORBID
-
- move.l (A0),D1 ; get pointer again after FORBID
- beq .ul20 ; no, rts (close a window)
-
- .ul10 move.l D1,A2 ; A2 = node
- cmp.b 13(A2),D2 ; waiting on our bit #?
- bne .ul18 ; no
- move.l 8(A2),A1 ; yes, signal the node
- moveq.l #$10,D0
- jsr _LVOSignal(A6) ; signal EVERYONE waiting
- .ul18 move.l (A2),D1 ; next
- bne .ul10
-
- .ul20
- PERMIT
- movem.l (sp)+,D2/A2/A6
- .ulrts rts
-
- ; FindName2(list:D0, name:A0)
- ;
- ; Search the node list as in FindName(), but also ignore
- ; NULL ln_name entries, which FindName() does not do. This
- ; routine will also return NULL if given an uninitialized
- ; list header (completely zero'd). Finally, it will not
- ; bother to do a string compare if the two pointers are
- ; the same.
-
- _lFindName2: movem.l A2/A3,-(sp)
- move.l D0,A1
- tst.l (A1) ; uninitialized list header
- beq .fn2fail
- .fn2loop move.l (A1),A1 ; get first/next node
- tst.l (A1) ; end of list?
- beq .fn2fail
- move.l LN_NAME(A1),D0 ; name
- beq .fn2loop ; NULL, skip
- cmp.l D0,A0 ; pointers are the same!
- beq .fn2succ ; don't bother w/cmp.
- move.l D0,A2
- move.l A0,A3
- .fn2l2 cmpm.b (A2)+,(A3)+
- bne .fn2loop
- tst.b -1(A2)
- bne .fn2l2
- .fn2succ move.l A1,D0
- movem.l (sp)+,A2/A3
- rts
- .fn2fail moveq.l #0,D0
- movem.l (sp)+,A2/A3
- rts
-
- #endasm
-
-