Annotation of kernel/bsd/dev/ppc/drvUSBCMD/driverservices.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
                      3:  *
                      4:  * @APPLE_LICENSE_HEADER_START@
                      5:  * 
                      6:  * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
                      7:  * Reserved.  This file contains Original Code and/or Modifications of
                      8:  * Original Code as defined in and that are subject to the Apple Public
                      9:  * Source License Version 1.1 (the "License").  You may not use this file
                     10:  * except in compliance with the License.  Please obtain a copy of the
                     11:  * License at http://www.apple.com/publicsource and read it before using
                     12:  * this file.
                     13:  * 
                     14:  * The Original Code and all software distributed under the License are
                     15:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
                     16:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
                     17:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
                     18:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
                     19:  * License for the specific language governing rights and limitations
                     20:  * under the License.
                     21:  * 
                     22:  * @APPLE_LICENSE_HEADER_END@
                     23:  */
                     24: 
                     25: /*
                     26:        File:           DriverServices.c
                     27: 
                     28:        Contains:       Native Driver support code for Device Manager
                     29: 
                     30:        Version:        xxx put version here xxx
                     31: 
                     32:        Written by:     Tom Saulpaugh
                     33: 
                     34:        Copyright:      � 1994-1997 by Apple Computer, Inc., all rights reserved.
                     35: 
                     36:        File Ownership:
                     37: 
                     38:                DRI:                            xxx put dri here xxx
                     39: 
                     40:                Other Contact:          xxx put other contact here xxx
                     41: 
                     42:                Technology:                     xxx put technology here xxx
                     43: 
                     44:        Writers:
                     45: 
                     46:                (JM3)   Jim Murphy
                     47:                (CSS)   Chas Spillar
                     48:                (KW)    Kevin Williams
                     49:                (MRN)   Matthew Nelson
                     50: 
                     51:        Change History (most recent first):
                     52: 
                     53:                <63>   18-Jun-97        JM3             Updated for cleaned up NanoKernelPriv/PPCInfoRecordsPriv.
                     54:                <62>     5/30/97        CSS             Delay() now takes an unsigned long * instead of a long * as its
                     55:                                                                        second parameter.
                     56:                <61>     3/18/97        KW              DelayFor Hardware was just looking at 5FFF EF80 to get the
                     57:                                                                        Processor Info structure. Now use the pointer located  at
                     58:                                                                        ProcessorInfo Ptr to get the pointer to the structure
                     59:                <60>      8/6/96        MRN             Changes to stop using private copy of 64 bit math routines and
                     60:                                                                        instead link against the real shipping version of the Math64Lib.
                     61:                <59>    10/30/95        MRN             Get rid of C version of SynchronizeIO that moved to
                     62:                                                                        DriverServices.s, and make file buildable with MrC.
                     63:                <58>     4/15/95        tjm             #1238020 - Fix DelayForHardware to handle 601 correctly. Moved
                     64:                                                                        fix back into DSL.m4
                     65:                <57>     4/14/95        tjm             #1238020 - Fix DelayForHardware to handle 601 correctly.
                     66:                <56>     4/10/95        TS              Fix bug in PBEnqueueLast
                     67:                <55>     4/10/95        TS              Optimize PBEnqueueLast for a queue of 1 or less elements
                     68:                <54>      4/6/95        TS              Fix PBDequeue
                     69:                <53>      4/5/95        TS              Rewrite PBEnqueueLast (Bug #1236338)
                     70:                <52>     3/31/95        TS              Bump preallocated data numbers and comment out debugging names
                     71:                                                                        before ROM freezes.
                     72:                <51>     3/30/95        TS              Retry CompareAndSwap in PBDequeue if element is at head of queue
                     73:                <50>     3/30/95        TS              Add OSTypes to each Globals Struct and reserve some space here
                     74:                                                                        as well.
                     75:                <49>     3/29/95        TS              Return last element in PBDequeueLast (Optimized path)
                     76:                <48>     3/28/95        TS              Optimize PBDequeue and PBDequeueLast for the first element
                     77:                <47>     3/27/95        TS              Fix bug #1232734 (IOCommandIsComplete return value)
                     78:                <46>     3/22/95        TS              Optimize fix for bug #1228034
                     79:                <45>     3/14/95        tjm             #1227300 - Insure that PStrNCmp works with all equal strings.
                     80:                <44>     3/14/95        tjm             #1228034 - insure that queueing functions are safe from
                     81:                                                                        interrupts
                     82:                <43>     2/21/95        tjm             #1220575 - Correct PStrNCat to handle strings > 255.
                     83:                <42>     2/20/95        tjm             #1220560 - Fix PStrCat to correctly handle dest strings > 128.
                     84:                <41>     1/27/95        tjm             #1214980 - PStrNCmp does not return correct value with null
                     85:                                                                        strings.
                     86:                <40>     1/25/95        tjm             #1214207 - Fix PBDequeueLast to delete if only one item in
                     87:                                                                        queue.
                     88:                <39>     1/25/95        tjm             #1214730 - Fix PStrCat to only Cat up to 255 chars.
                     89:                <38>     1/19/95        tjm             Break out DSLInit routine to aid in debugging
                     90:                <37>     1/19/95        tjm             #1211193 - Allow Dequeuing from head.
                     91:                <36>     1/18/95        tjm             #1212320 - Insure PBEnqueueLast is re-entrant.
                     92:                <35>     1/18/95        tjm             #1203060 - Make a Global Data Lib for the DSL.
                     93:                <34>     1/16/95        tjm             #1203145 - Add DelayForHardware so drivers can call delay
                     94:                                                                        routine at InterruptTime.
                     95:                <33>     1/10/95        tjm             #1210156 - Make sure PBQueueDelete correctly deallocated
                     96:                                                                        preallocated qHdrs.
                     97:                <32>     1/10/95        tjm             #1210154 - return noErr for unaligned qHdr allocation.
                     98:                <31>     1/10/95        tjm             #1207351 - Make sure PStrLen returns correct value.
                     99:                <30>     1/10/95        tjm             #1207081 - Fix the PStr functions to handle lengths correctly
                    100:                <29>      1/9/95        tjm             #1208049 - return paramErr if CSI fails.
                    101:                <28>      1/9/95        tjm             #1209423 - correctly handle empty qHdr when it is empty
                    102:                <27>      1/9/95        MN              Add a call to UpTime in the CFM initialization function to
                    103:                                                                        initialize the timebase variable in the new timing functions.
                    104:                <26>    12/21/94        MN              Restore checkins 18 through 24 and include the fixes checked
                    105:                                                                        into 25.
                    106:                <25>    12/21/94        MN              Added alignment support to PBQueueCreate and PBQueueDelete for Marconi_v16c2
                    107:                                                                        which would have checked in over the top of checkins 18 through 24.
                    108:                <24>    12/20/94        tjm             #1206624 - Fix PBDequeueLastSync to correctly dequeue item.
                    109:                <23>    12/19/94        tjm             #1204196 - fix this again.
                    110:                <22>    12/16/94        tjm             #1206622 - eliminate reentrantcy problem with PBDequeueSync.
                    111:                <21>    12/16/94        tjm             #1203051 - added PBEnqueueLast function
                    112:                <20>    12/15/94        tjm             #1204196 - call PBQueueInit when PBQueueCreate is successful.
                    113:                <19>    12/15/94        tjm             #1204193 - initialize qFlags in qHeader of PBQueueInit.
                    114:                <18>    12/15/94        tjm             #1203057 - increment the number of SWI's to 32
                    115:                <17>     12/5/94        tjm             #1202888 - Fix PBDequeue to not corrupt queue with 2 elements
                    116:                <16>     12/5/94        tjm             #1202776 - Fix PBDequeue to return qErr for nonexistant element.
                    117:                <15>     12/5/94        tjm             #1201314 - correctly queue secondary interrupts
                    118:                <14>    11/15/94        tjm             #1195428 - Fix function prototypes to correctly define src ptrs
                    119:                                                                        as const.
                    120:                <13>     11/3/94        tjm             fix DelayFor to use low end of 64 bit divide, ID#1197350
                    121:                <12>    10/25/94        tjm             Call TimerInitialize, SIHInitialize, and MemoryInitialze to fix
                    122:                                                                        #1192590
                    123:                <11>     9/15/94        MN              Add call in DSL_Init to startup Interrupt Manager and change
                    124:                                                                        PBQueueInit to return an error code;
                    125:                <10>     8/31/94        TS              Make the DSL_Init check for failures
                    126:                 <9>     8/29/94        TS              Add a call to the CFM init routine to calculate physical RAM
                    127:                                                                        size using the ROM physical space table
                    128:                 <8>     8/25/94        TS              Add DelayFor and Move BlockCopy to MemoryManagement.c
                    129:                 <7>     8/24/94        TS              Add in checks for correct execution levels
                    130:                 <6>     8/24/94        TS              Make DSL_Init return noErr to library will load
                    131:                 <5>     8/24/94        TS              Build ExecutionLevel Func
                    132:                 <4>     8/23/94        TS              Implement SoftwareInterrupts
                    133:                 <3>     8/18/94        TS              Add more queue functions
                    134:                 <2>     8/17/94        JF              Changes from PCI developer kitchen
                    135:                 <1>      8/5/94        JF              first checked in
                    136: 
                    137: */
                    138: 
                    139: 
                    140: 
                    141: //
                    142: // Source to the NuDriver Support Services Library
                    143: //
                    144: 
                    145: //#include <Types.h>
                    146: //#include <Strings.h>
                    147: //#include <Files.h>
                    148: //#include <MixedMode.h>
                    149: //#include <LowMem.h>
                    150: //#include <Math64.h>
                    151: 
                    152: // Get Prototypes of the Exported Services First,...
                    153: 
                    154: #include "driverservices.h"
                    155: #include "driverservicespriv.h"
                    156: #include "PPCInfoRecordsPriv.h"
                    157: #include "rhap_local.h"
                    158: 
                    159: // The Driver Services Follow,...
                    160: 
                    161: 
                    162: OSErr InitSwis (void);
                    163: 
                    164: /////////////////////////////////////////////////////////////////////////////////
                    165: //
                    166: //     Command Processing
                    167: //
                    168: //
                    169: 
                    170: /*-------------------------------------------------------------------------------
                    171: 
                    172: Routine:       IOCommandIsComplete     -       Marks I/O Command as Done.
                    173: 
                    174: Function:      Returns IODone result from Device Manager
                    175: 
                    176: Input:         theID           - ID of the in-progress I/O command.
                    177:                        theResult       - the result value of the command. (Low 16-bits are placed in IOPB)
                    178: 
                    179: Result:                noErr   or 
                    180: -------------------------------------------------------------------------------*/
                    181: /*naga
                    182: enum {
                    183:        uppIODoneProcInfo =             kRegisterBased
                    184:                                                |       REGISTER_ROUTINE_PARAMETER(1,kRegisterA1,kFourByteCode)
                    185:                                                |       REGISTER_ROUTINE_PARAMETER(2,kRegisterD0,kFourByteCode)
                    186: };
                    187: 
                    188: 
                    189: OSErr  IOCommandIsComplete             (       IOCommandID             theID,
                    190:                                                                        OSErr                   theResult)
                    191: {
                    192:        ParmBlkPtr       The_Pb         = (ParmBlkPtr)theID;
                    193:        OSErr           *The_Result = (OSErr *)(&The_Pb -> ioParam.ioCmdAddr);
                    194:        
                    195:        if (theID == nil)
                    196:                return paramErr;
                    197: 
                    198:        *The_Result = theResult;
                    199:        
                    200:        (void)CallUniversalProc (       LMGetJIODone(),
                    201:                                                                uppIODoneProcInfo,
                    202:                                                                The_Pb,
                    203:                                                                1 );
                    204:        return noErr;
                    205: }
                    206: naga */
                    207: /*-------------------------------------------------------------------------------
                    208: 
                    209: Routine:       GetIOCommandInfo        -       Returns info about an in-progress I/O command.
                    210: 
                    211: Function:      Returns IOCommandContents, IOCommandCode, and IOCommandKind.
                    212: 
                    213: Input:         theID   - ID of the in-progress I/O command.
                    214: 
                    215: Output:                theContents             - pointer to the IOPB or Initialize/Finalize Contents.
                    216:                        theCommand              - the command code
                    217:                        theKind                 - the kind of I/O (Sync, Async, or Immed)
                    218:                        
                    219: Result:                noErr   
                    220: -------------------------------------------------------------------------------*/
                    221: /*naga
                    222: OSErr  GetIOCommandInfo                (       IOCommandID                             theID,
                    223:                                                                    IOCommandContents   *       theContents,
                    224:                                                                        IOCommandCode           *       theCommand,
                    225:                                                                        IOCommandKind           *       theKind )
                    226: {
                    227:        IOCommandContents       The_Contents;
                    228:        ParmBlkPtr                      The_Pb          = (ParmBlkPtr)theID;
                    229: 
                    230:        if (theID == nil)
                    231:                return paramErr;
                    232: 
                    233:        The_Contents . pb = The_Pb;
                    234:        
                    235:        *theContents = The_Contents;
                    236:        *theCommand  = (The_Pb  -> ioParam.ioTrap & 0x00ff);
                    237:        *theKind         = ((The_Pb -> ioParam.ioTrap & 0xff00) >> 8);
                    238:        
                    239:        return noErr;
                    240: }
                    241: */
                    242: 
                    243: /////////////////////////////////////////////////////////////////////////////////
                    244: //
                    245: //     Queues
                    246: //
                    247: //
                    248: 
                    249: /*-------------------------------------------------------------------------------
                    250: 
                    251: Routine:       PBQueueInit     -       Initialize a Queue (@ NON-Interrupt-lvl and SIH-lvl)
                    252: 
                    253: -------------------------------------------------------------------------------*/
                    254: 
                    255: OSErr PBQueueInit(QHdrPtr qHeader)
                    256: {
                    257:        qHeader -> qHead = nil;
                    258:        qHeader -> qTail = nil;
                    259:        qHeader -> qFlags = 0x0000;
                    260:        
                    261:        return noErr;
                    262: }
                    263: 
                    264: /*-------------------------------------------------------------------------------
                    265: 
                    266: Routine:       PBQueueCreate   -       Initialize a Queue (@ NON-Interrupt lvl)
                    267: 
                    268: -------------------------------------------------------------------------------*/
                    269: 
                    270: OSErr PBQueueCreate(QHdrPtr *qHeader)
                    271: {
                    272:        Ptr **theQueue;
                    273:        
                    274:        if (CurrentExecutionLevel() != kTaskLevel)
                    275:        {
                    276:                // SysDebugStr ((StringPtr)"\pPBQueueCreate not called at Task Level!");
                    277:                // 11/30/98 Adam return -1;
                    278:        }
                    279:        
                    280:        *qHeader = nil;
                    281:        theQueue = (Ptr **)PoolAllocateResident (sizeof(QHdr)+sizeof(short)+sizeof(Ptr),true);
                    282:        if (theQueue != nil)
                    283:        {
                    284:                // Store orig ptr in first 4 bytes.
                    285:                *theQueue = (Ptr *)theQueue;
                    286:                theQueue++;
                    287:                
                    288:                // Are we not aligned?
                    289:                if ( ((UInt32)theQueue & 3) == 0 )
                    290:                {
                    291:                        short *pattern = (short *)theQueue;
                    292:                        
                    293:                        *pattern++      = 0x4D4E;
                    294:                        *qHeader        = (QHdrPtr)pattern;
                    295:                        return noErr;
                    296:                }
                    297:                else
                    298:                {
                    299:                        *qHeader        = (QHdrPtr)theQueue;
                    300:                        return noErr;
                    301:                }
                    302:        }
                    303:        else
                    304:                return mFulErr;
                    305: }
                    306: 
                    307: /*-------------------------------------------------------------------------------
                    308: 
                    309: Routine:       PBQueueDelete   -       Finalize a Queue (@ NON-Interrupt lvl)
                    310: 
                    311: -------------------------------------------------------------------------------*/
                    312: 
                    313: OSErr PBQueueDelete(QHdrPtr qHeader)
                    314: {
                    315:        Ptr       **theMemory;
                    316:        UInt16 *pattern = (UInt16 *)qHeader;
                    317:        
                    318:        if (CurrentExecutionLevel() != kTaskLevel)
                    319:        {
                    320:                // SysDebugStr ((StringPtr)"\pPBQueueDelete not called at Task Level!");
                    321:                return -1;
                    322:        }
                    323:        
                    324:        if (*--pattern == 0x4D4E)
                    325:                qHeader = (QHdrPtr)((UInt32)(qHeader) - sizeof(UInt16));
                    326:                
                    327:        theMemory = (Ptr **)qHeader;
                    328:        theMemory--;
                    329:        
                    330:        if (*theMemory != (Ptr *)theMemory)
                    331:        {
                    332:                // SysDebugStr ((StringPtr)"\pPBQueueDelete not a Queue Header!");
                    333:                return -1;
                    334:        }
                    335: 
                    336:        (void)PoolDeallocate(theMemory);
                    337:        return noErr;
                    338: }
                    339: 
                    340: /*-------------------------------------------------------------------------------
                    341: 
                    342: Routine:       PBEnqueueLast   -       Add an IOPB to the end of a Request Queue. (@ Any Exec-lvl)
                    343:                                                                (Optimized for queue size of 1 or less)
                    344: 
                    345: -------------------------------------------------------------------------------*/
                    346: 
                    347: OSErr PBEnqueueLast(QElemPtr qElement, QHdrPtr qHeader)
                    348: {
                    349:        QElemPtr currElemPtr;
                    350:        UInt16 sr;
                    351:        
                    352:        // New element will be at end of queue.
                    353:        qElement -> qLink = nil;
                    354: 
                    355:        // Currently an empty queue?
                    356:        while ( qHeader -> qHead == nil )
                    357:        {
                    358:                if (CompareAndSwap ((UInt32) nil, (UInt32) qElement, (UInt32 *) &qHeader->qHead))
                    359:                        return noErr;
                    360:        }
                    361:        
                    362:        // Multi-element queue,...
                    363:        
                    364:        // Do it the sure, but slow way.
                    365:        sr = Disable68kInterrupts();
                    366: 
                    367:        // Entire queue empty?
                    368:        if ( qHeader -> qHead == nil )
                    369:        {
                    370:                // Add at head of queue
                    371:                qHeader -> qHead = qElement;
                    372:        }
                    373:        else
                    374:        {
                    375:                // Else, Get first element in queue.
                    376:                currElemPtr     = (QElemPtr)qHeader->qHead;
                    377:                
                    378:                // Move toward the end of the queue,...
                    379:                while ( currElemPtr -> qLink != nil )
                    380:                {       
                    381:                        currElemPtr     = currElemPtr -> qLink;
                    382:                }
                    383:        
                    384:                currElemPtr -> qLink = qElement;
                    385:        }
                    386:        
                    387:        Restore68kInterrupts(sr);
                    388:        return noErr;
                    389: }
                    390: 
                    391: /*-------------------------------------------------------------------------------
                    392: 
                    393: Routine:       PBEnqueue       -       Add an IOPB to Head of Request Queue. (@ Any Exec-lvl)
                    394: 
                    395: Function:      Returns (nothing)
                    396:                        
                    397: Result:                void    
                    398: -------------------------------------------------------------------------------*/
                    399: 
                    400: void PBEnqueue(QElemPtr qElement, QHdrPtr qHeader)
                    401: {
                    402:        do {
                    403:                qElement -> qLink = qHeader->qHead;
                    404:        } while (CompareAndSwap ((UInt32) qElement->qLink, (UInt32) qElement,
                    405:                                                                                        (UInt32 *) &qHeader->qHead) == false);
                    406: }
                    407: 
                    408: 
                    409: /*-------------------------------------------------------------------------------
                    410: 
                    411: Routine:       PBDequeue       -       Remove an IOPB from a Request Queue.  (@ Any Exec-lvl)
                    412: 
                    413: Function:      Returns (nothing)
                    414:                        
                    415: Result:                void    
                    416: -------------------------------------------------------------------------------*/
                    417: 
                    418: static OSErr PBDequeueSync(QElemPtr qElement, QHdrPtr qHeader)
                    419: {
                    420:        QElemPtr prevElemPtr, currElemPtr;
                    421:        OSErr    result = noErr;
                    422:        UInt16  sr;
                    423:        
                    424:        // Validate params.
                    425:        if ( (qElement == nil) || (qHeader == nil) )
                    426:                return paramErr;
                    427:                
                    428:        sr = Disable68kInterrupts();
                    429:        
                    430:        currElemPtr = (QElemPtr)qHeader->qHead;
                    431:        prevElemPtr = nil;
                    432:        
                    433:        // Find the one we want.
                    434:        while ( currElemPtr && (currElemPtr != qElement) )
                    435:        {
                    436:                // Advance the cause.
                    437:                prevElemPtr = currElemPtr;
                    438:                currElemPtr = currElemPtr -> qLink;
                    439:        }
                    440:        
                    441:        // We find it?
                    442:        if ( currElemPtr )
                    443:        {
                    444:                // Middle of the queue somewhere?
                    445:                if ( prevElemPtr )
                    446:                        prevElemPtr -> qLink = currElemPtr ->qLink;
                    447:                else
                    448:                        qHeader->qHead = currElemPtr ->qLink;
                    449:                
                    450:                currElemPtr -> qLink = nil;
                    451:        }
                    452:        else
                    453:                result = qErr; // not on the list.
                    454:        
                    455:        Restore68kInterrupts(sr);
                    456:        return result;
                    457: }
                    458: 
                    459: 
                    460: OSErr PBDequeue(QElemPtr qElement, QHdrPtr qHeader)
                    461: {
                    462:        // Optimize for common case of 1 element on the queue.
                    463:        
                    464:        // First one on the queue?
                    465:        while ( qHeader -> qHead == qElement )
                    466:        {
                    467:                // If the element is still at the head of the queue,... Remove it, and we are done.
                    468:                if (CompareAndSwap ((UInt32) qElement,
                    469:                                                        (UInt32) qElement -> qLink,
                    470:                                                        (UInt32 *) &qHeader->qHead) == true)
                    471:                {
                    472:                        qElement -> qLink = nil;
                    473: 
                    474:                        return noErr;
                    475:                }
                    476:        }
                    477:        
                    478:        // Multiple elements on the queue.
                    479:        return PBDequeueSync (qElement, qHeader);
                    480: }
                    481: 
                    482: /*-------------------------------------------------------------------------------
                    483: 
                    484: Routine:       PBDequeueFirst  -       Remove First Element on a Queue  (@ Any Exec-lvl)
                    485: 
                    486: Result:                noErr or qErr
                    487: -------------------------------------------------------------------------------*/
                    488: 
                    489: OSErr PBDequeueFirst(QHdrPtr qHeader, QElemPtr *theFirstqElem)
                    490: {
                    491:        QElemPtr qElement;
                    492: 
                    493:        do {
                    494:                // Get Queue Head Ptr
                    495:                qElement = qHeader -> qHead;
                    496:                
                    497:                // Empty Queue?
                    498:                if ( qElement == nil )
                    499:                {
                    500:                        if ( theFirstqElem )
                    501:                                *theFirstqElem = nil;
                    502:                                
                    503:                        return qErr;    
                    504:                }
                    505:                
                    506:                // If the element is still at the head of the queue,... Remove it, and we are done.
                    507:                if (CompareAndSwap ((UInt32) qElement,
                    508:                                                        (UInt32) qElement -> qLink,
                    509:                                                        (UInt32 *) &qHeader->qHead) == true)
                    510:                {
                    511:                        if ( theFirstqElem )
                    512:                                *theFirstqElem = qElement;
                    513:                                
                    514:                        qElement -> qLink = nil;
                    515: 
                    516:                        return noErr;
                    517:                }
                    518:        } while (1);
                    519: }
                    520: 
                    521: /*-------------------------------------------------------------------------------
                    522: 
                    523: Routine:       PBDequeueLast   -       Remove Last Element on a Queue  (@ Any Exec-lvl)
                    524: 
                    525: Result:                noErr or qErr
                    526: -------------------------------------------------------------------------------*/
                    527: 
                    528: OSErr PBDequeueLast(QHdrPtr qHeader, QElemPtr *theLastqElem)
                    529: {
                    530:        QElemPtr currElemPtr, prevElemPtr;
                    531:        OSErr   result = noErr;
                    532:        UInt16 sr;
                    533:        
                    534:        if ( theLastqElem )
                    535:                *theLastqElem = nil;
                    536:                
                    537:        sr = Disable68kInterrupts();
                    538: 
                    539:        // Get Queue Head Ptr and our initial previous ptr
                    540:        if ((prevElemPtr = qHeader -> qHead) == nil)
                    541:                result = qErr; // q is empty
                    542:        else
                    543:        {
                    544:                // Get head of queue
                    545:                currElemPtr     = (QElemPtr)qHeader->qHead;
                    546:                
                    547:                // Move toward the end of the queue,...
                    548:                while ( currElemPtr -> qLink != nil )
                    549:                {       
                    550:                        prevElemPtr     = currElemPtr;
                    551:                        currElemPtr     = currElemPtr ->qLink;
                    552:                }
                    553:        
                    554:                // Remove last one from the queue.
                    555:                prevElemPtr->qLink = nil;
                    556:                
                    557:                // If last was also the first, nil out qheader.
                    558:                if ( currElemPtr == qHeader -> qHead )
                    559:                        qHeader -> qHead = nil;
                    560:        
                    561:                // Return last element to caller.
                    562:                if ( theLastqElem )
                    563:                        *theLastqElem = currElemPtr;
                    564:        }
                    565:        
                    566:        Restore68kInterrupts(sr);
                    567:        return result;
                    568: }
                    569: 
                    570: /////////////////////////////////////////////////////////////////////////////////
                    571: //
                    572: //     Strings
                    573: //
                    574: //
                    575: 
                    576: /*-------------------------------------------------------------------------------
                    577: 
                    578: Routine:       CStrCopy        -       Copy string of chars from src to dst.
                    579: 
                    580: Function:      Copies characters upto and including the null character from 'src' to
                    581:                        'dst' char strings.
                    582: 
                    583: Note:          This routine assumes the two strings do not overlap. It would be bad.
                    584:                        
                    585: Input:         src             - pointer to the source string of char's to copy.
                    586: 
                    587: Output:                dst             - pointer to the destination string of char's.
                    588:                        
                    589: Result:                dst             - a pointer to the destination string is returned.
                    590: -------------------------------------------------------------------------------*/
                    591: 
                    592: char   *CStrCopy       (char *dst,     const char      *src)
                    593: {
                    594:        char    *pos = dst;
                    595:        
                    596:        while ( (*pos++ = *src++) != 0)                         // copy src to dst
                    597:                ;
                    598:                
                    599:        return dst;
                    600: }
                    601: 
                    602: 
                    603: /*-------------------------------------------------------------------------------
                    604: 
                    605: Routine:       PStrCopy        -       Copy string of chars from src to dst.
                    606: 
                    607: Function:      Copies characters upto and including the null character from 'src' to
                    608:                        'dst' char strings.
                    609: 
                    610: Note:          This routine assumes the two strings do not overlap. It would be bad.
                    611:                        
                    612: Input:         src             - pointer to the source string of char's to copy.
                    613: 
                    614: Output:                dst             - pointer to the destination string of char's.
                    615:                        
                    616: Result:                dst             - a pointer to the destination string is returned.
                    617: -------------------------------------------------------------------------------*/
                    618: 
                    619: StringPtr      PStrCopy        (StringPtr dst, ConstStr255Param src)
                    620: {
                    621:        UInt8     len;
                    622:        char     *s,*d;
                    623:        
                    624:        s               = (char *)src;
                    625:        d               = (char *)dst;
                    626:        len             = *src;
                    627:        
                    628:        *d++ = *s++;
                    629:        while (len-- != 0)
                    630:                *d++ = *s++;
                    631:        
                    632:        return dst;
                    633: }
                    634: 
                    635: 
                    636: /*-------------------------------------------------------------------------------
                    637: 
                    638: Routine:       CStrNCopy       -       Copy at most n characters.
                    639: 
                    640: Function:      Copies upto 'max' characters from 'src' to 'dst' char strings.
                    641:                        If 'src' string is shorter than 'max', the 'dst string will be
                    642:                        padded with null characters. If 'src' string is longer than 'max'
                    643:                        the 'dst' string will NOT be null terminated.
                    644:                        
                    645:                        See ANSI X3.159-1989 p.106 - "strncpy"
                    646: 
                    647: 
                    648: Input:         src             - pointer to the source string of char's to copy.
                    649:                        max             - maximum number of characters to copy.
                    650:                        
                    651: 
                    652: Output:                dst             - pointer to the destination string of char's.
                    653:                        
                    654: Result:                dst             - a pointer to the destination string is returned.
                    655: -------------------------------------------------------------------------------*/
                    656: 
                    657: char   *CStrNCopy      (char *dst,     const char      *src,   UInt32  max)
                    658: {
                    659:        char    *pos = dst;
                    660:        
                    661:        max++;                                                                  // bump up max so we can predecrement in tests
                    662:        do {                                                                    // copy upto max chars to dst
                    663:                if (--max == 0)         return dst;             // exit if we've copied max chars
                    664:        } while ( (*pos++ = *src++) != 0);                              // copy char & test
                    665: 
                    666:        while ( --max ) *pos++ = 0;                             // pad remainder of string with nulls
                    667:                                                                                        // unless we have already reached max.
                    668:        return dst;
                    669: }
                    670: 
                    671: 
                    672: 
                    673: /*-------------------------------------------------------------------------------
                    674: 
                    675: Routine:       PStrNCopy       -       Copy string of chars from src to dst.
                    676: 
                    677: Function:      Copies max characters from 'src' to 'dst' char strings.
                    678: 
                    679: Input:         src             - pointer to the source string of char's to copy.
                    680: 
                    681: Output:                dst             - pointer to the destination string of char's.
                    682:                        
                    683: Result:                dst             - a pointer to the destination string is returned.
                    684: -------------------------------------------------------------------------------*/
                    685: 
                    686: StringPtr      PStrNCopy       (StringPtr dst, ConstStr255Param src, UInt32    max)
                    687: {
                    688:        UInt8   len;
                    689:        char    *s,*d;
                    690:        char    count = 0;
                    691:        
                    692:        s               = (char *)src;
                    693:        d               = (char *)dst;
                    694:        len             = *s;
                    695:        
                    696:        do {                                                    
                    697:                if ( (max-- == 0) || (len-- == 0))
                    698:                        break;                          
                    699: 
                    700:                *++d = *++s;
                    701:                count += 1;
                    702: 
                    703:        } while ( 1 );
                    704:        
                    705:        if ( count )
                    706:                *dst = count;
                    707:                
                    708:        return dst;
                    709: }
                    710: 
                    711: 
                    712: /*-------------------------------------------------------------------------------
                    713: 
                    714: Routine:       CStrCat -       Append 'src' char string onto 'dst'.
                    715: 
                    716: Function:      Appends characters from 'src' to 'dst' char strings.
                    717:                        The initial character of 'src' overwrites the null character at
                    718:                        the end of 'dst'. A terminating null character is ALWAYS appended.
                    719:                        
                    720: 
                    721: Input:         src             - pointer to the source string of char's to append.
                    722: 
                    723: Output:                dst             - pointer to the destination string of char's.
                    724:                        
                    725:                        
                    726: Result:                dst             - a pointer to the destination string is returned.
                    727: -------------------------------------------------------------------------------*/
                    728: 
                    729: char   *CStrCat        (char *dst,     const char *src)
                    730: {
                    731:        char    *pos = dst;
                    732:        
                    733:        while ( *pos++ )                                                // find the end of dst string
                    734:                ;
                    735:                
                    736:        --pos;                                                                  // backup to point to null word
                    737: 
                    738:        while ( (*pos++ = *src++) != 0)                 // copy src to dst      
                    739:                ;
                    740:                
                    741:        return dst;
                    742: }
                    743: 
                    744: 
                    745: 
                    746: 
                    747: /*-------------------------------------------------------------------------------
                    748: 
                    749: Routine:       PStrCat -       Append 'src' char string onto 'dst'.
                    750: 
                    751: Function:      Appends characters from 'src' to 'dst' char strings.                    
                    752: 
                    753: Input:         src             - pointer to the source string of char's to append.
                    754: 
                    755: Output:                dst             - pointer to the destination string of char's.
                    756:                        
                    757:                        
                    758: Result:                dst             - a pointer to the destination string is returned.
                    759: -------------------------------------------------------------------------------*/
                    760: 
                    761: StringPtr PStrCat      (StringPtr dst, ConstStr255Param src)
                    762: {
                    763:        UInt8   *pos = (UInt8 *)dst;
                    764:        UInt8   *d       = (UInt8 *)dst;
                    765:        UInt8   *s       = (UInt8 *)src;
                    766:        UInt8   len  = *s++;
                    767:        UInt8   dlen  = *d;
                    768: 
                    769: 
                    770:        if (((UInt32)len + (UInt32)dlen) > (UInt32)255)
                    771:        {
                    772:                len = 255 - dlen;
                    773:        }
                    774:        pos += (*pos) + 1;                                              // pos at end of string.
                    775:        
                    776:        while ( len-- != 0 )
                    777:        {
                    778:                *pos++ = *s++;                                          // car src to dst       
                    779:                (*d) += 1;                                                      // dump new string length
                    780:        }
                    781:        
                    782:        return dst;
                    783: }
                    784: 
                    785: 
                    786: 
                    787: /*-------------------------------------------------------------------------------
                    788: 
                    789: Routine:       CStrNCat        -       Append at most n characters.
                    790: 
                    791: Function:      Appends upto 'max' characters from 'src' to 'dst' char strings.
                    792:                        The initial character of 'src' overwrites the null character at
                    793:                        the end of 'dst'. A terminating null character is ALWAYS appended.
                    794:                        Thus, the maximum length of 'dst' could be CStrLen(dst)+max+1.
                    795:                        
                    796:                        See ANSI X3.159-1989 p.164 - "strncat"
                    797: 
                    798: 
                    799: Input:         src             - pointer to the source string of char's to append.
                    800:                        max             - maximum number of characters to append.
                    801:                        
                    802: 
                    803: Output:                dst             - pointer to the destination string of char's.
                    804:                        
                    805:                        
                    806: Result:                dst             - a pointer to the destination string is returned.
                    807: -------------------------------------------------------------------------------*/
                    808: 
                    809: char   *CStrNCat       (char *dst,     const char *src,        UInt32  max)
                    810: {
                    811:        char    *pos = dst;
                    812:        
                    813:        while ( *pos++ )                                                // find the end of dst string
                    814:                ;
                    815:                
                    816:        --pos;                                                                  // backup to point to null char
                    817:        ++max;                                                                  // bump up max so we can predecrement test
                    818:        while ( --max && ( (*pos++ = *src++) != 0))     // append upto max chars to dst
                    819:                ;
                    820:                
                    821:        if (max == 0)                                                   // if we reached max chars
                    822:                *pos = 0;                                                       // append null character
                    823:                
                    824:        return dst;
                    825: }
                    826: 
                    827: 
                    828: 
                    829: /*-------------------------------------------------------------------------------
                    830: 
                    831: Routine:       PStrNCat        -       Append 'src' char string onto 'dst'.
                    832: 
                    833: Function:      Appends characters from 'src' to 'dst' char strings.                    
                    834: 
                    835: Input:         src             - pointer to the source string of char's to append.
                    836: 
                    837: Output:                dst             - pointer to the destination string of char's.
                    838:                        
                    839:                        
                    840: Result:                dst             - a pointer to the destination string is returned.
                    841: -------------------------------------------------------------------------------*/
                    842: 
                    843: StringPtr PStrNCat     (StringPtr dst, ConstStr255Param src, UInt32    max)
                    844: {
                    845:        UInt8   *pos = (UInt8 *)dst;
                    846:        UInt8   *d       = (UInt8 *)dst;
                    847:        UInt8   *s       = (UInt8 *)src;
                    848:        UInt8   len  = *s++;
                    849:        
                    850: 
                    851:        len = (((UInt32)*src + (UInt32)*dst) < (UInt32)255) ? (UInt32)*src : (UInt32)255 - (UInt32)*dst;
                    852:        
                    853:        pos += (*pos) + 1;                                              // pos at end of string.
                    854: 
                    855:        while ( (max-- != 0) && (len-- != 0) )
                    856:        {
                    857:                *pos++ = *s++;                                          // car src to dst       
                    858:                (*d) += 1;                                                      // dump new string length
                    859:        }
                    860:        
                    861:        return dst;
                    862: }
                    863: 
                    864: 
                    865: /*-------------------------------------------------------------------------------
                    866: 
                    867: Routine:       PStrToCStr      -       convert Pascal string 'src' to char string 'dst'.
                    868: 
                    869: Function:      Converts 1 byte Pascal string chars to 2 byte char string by prefixing
                    870:                        the ASCII byte with 0x00. The char string is terminated with a 2 byte
                    871:                        null character, 0x0000.
                    872:                        
                    873: 
                    874: Input:         src             - pointer to the Pascal source string.
                    875: 
                    876: Output:                dst             - pointer to the destination string of char's.
                    877: -------------------------------------------------------------------------------*/
                    878: 
                    879: void   PStrToCStr      (char   *dst,   ConstStr255Param src)
                    880: {
                    881:        unsigned char   len;
                    882:        
                    883:        len = 1 + *src++;                                                       // add 1 so we can predecrement
                    884:        while (--len)                                                           // for each char in src...
                    885:        {
                    886:                *dst++ = (char) *src++;                                 // cast & copy chars
                    887:        }
                    888:        
                    889:        *dst = 0;                                                                       // append null char
                    890: }
                    891: 
                    892: 
                    893: 
                    894: /*-------------------------------------------------------------------------------
                    895: 
                    896: Routine:       CStrToPStr      -       convert char string 'src' to Pascal string 'dst'.
                    897: 
                    898: Function:      Converts 2 byte char string chars to 1 byte Pascal string by lopping
                    899:                        off the high byte. This is NOT considered sound foreign policy, and we
                    900:                        will have to accomodate our international brethren lest they be displeased
                    901:                        with us. But, it is useful for development and debugging.
                    902:                        
                    903: 
                    904: Input:         src             - pointer to the char source string.
                    905: 
                    906: Output:                dst             - pointer to the Pascal destination string.
                    907: -------------------------------------------------------------------------------*/
                    908: 
                    909: void   CStrToPStr      (Str255         dst,    const char      *src)
                    910: {
                    911:        UInt32                   len    = 0;
                    912:        const char      *s2     = src;
                    913:        
                    914:        while (*src++)                                                  // how long is it?
                    915:                ++len;
                    916:        
                    917:        if (len > 255)  len = 255;                              // truncate to 255 chars
                    918:        
                    919:        *dst++ = (unsigned char) len++;                 // stuff length byte &
                    920:                                                                                        // increment so we can predecrement
                    921:        while (--len)
                    922:                *dst++ = *s2++;                                         // copy len chars
                    923: }
                    924: 
                    925: 
                    926: 
                    927: /////////////////////////////// Compare Routines ////////////////////////////////
                    928: 
                    929: 
                    930: /*-------------------------------------------------------------------------------
                    931: 
                    932: Routine:       CStrCmp -       Compare two char strings.
                    933: 
                    934: Function:      Compares the char strings s1 and s2 by comparing the values of
                    935:                        corresponding characters in each string. It does NOT take into
                    936:                        consideration case, diacriticals, or other localization requirements.
                    937: 
                    938: 
                    939: Input:         s1              - pointer to char string.
                    940:                        s2              - pointer to char string.
                    941: 
                    942:                        
                    943: Result:                -1              - s1 < s2
                    944:                         0              - s1 = s2
                    945:                         1              - s1 > s2
                    946: -------------------------------------------------------------------------------*/
                    947: 
                    948: short  CStrCmp (const char *s1,        const char      *s2)
                    949: {
                    950:        char            chr;
                    951:        
                    952:        while ( (chr = *s1++) != 0)
                    953:        { 
                    954:                if ( *s2++ != chr )
                    955:                {
                    956:                        if ( chr < *--s2 )
                    957:                                return -1;
                    958:                        return 1;
                    959:                }
                    960:        }
                    961:                                                // here chr==0 and s2 has not advanced
                    962:        if(*s2 == 0)
                    963:                return 0;
                    964:        return -1;
                    965: }
                    966: 
                    967: 
                    968: 
                    969: /*-------------------------------------------------------------------------------
                    970: 
                    971: Routine:       PStrCmp -       Compare two char strings.
                    972: 
                    973: Function:      Compares the char strings s1 and s2 by comparing the values of
                    974:                        corresponding characters in each string. It does NOT take into
                    975:                        consideration case, diacriticals, or other localization requirements.
                    976: 
                    977: 
                    978: Input:         s1              - pointer to Pascal string.
                    979:                        s2              - pointer to Pascal string.
                    980: 
                    981:                        
                    982: Result:                -1              - s1 < s2
                    983:                         0              - s1 = s2
                    984:                         1              - s1 > s2
                    985: -------------------------------------------------------------------------------*/
                    986: 
                    987: short  PStrCmp (ConstStr255Param str1, ConstStr255Param str2)
                    988: {
                    989:        UInt8           s1len,s2len;
                    990:        char            chr, *s1, *s2;
                    991:        
                    992:        s1              = (char *)str1;
                    993:        s2              = (char *)str2;
                    994:        s1len   = *s1++;
                    995:        s2len   = *s2++;
                    996:        
                    997:        while (s1len && s2len)
                    998:        { 
                    999:                s1len--; s2len--;
                   1000:                chr = *s1++;
                   1001:                if ( *s2++ != chr )
                   1002:                {
                   1003:                        if ( chr < *--s2 )
                   1004:                                return -1;
                   1005:                        return 1;
                   1006:                }
                   1007:        }
                   1008:                                                
                   1009:        if((s2len == 0) && (s1len == 0))
                   1010:                return 0;
                   1011: 
                   1012:        if(s1len)
                   1013:                return 1;
                   1014:        return -1;
                   1015: }
                   1016: 
                   1017: 
                   1018: 
                   1019: /*-------------------------------------------------------------------------------
                   1020: 
                   1021: Routine:       CStrNCmp        -       Compare the first N characters of two char strings.
                   1022: 
                   1023: Function:      Compares the first N char strings s1 and s2 by comparing the values
                   1024:                        of corresponding characters in each string. It does NOT take into
                   1025:                        consideration case, diacriticals, or other localization requirements.
                   1026: 
                   1027: 
                   1028: Input:         s1              - pointer to char string.
                   1029:                        s2              - pointer to char string.
                   1030:                        max             - the number of characters to compare.
                   1031: 
                   1032:                        
                   1033: Result:                -1              - s1 < s2
                   1034:                         0              - s1 = s2
                   1035:                         1              - s1 > s3
                   1036: -------------------------------------------------------------------------------*/
                   1037: 
                   1038: short  CStrNCmp        (const char *s1,        const char      *s2,    UInt32  max)
                   1039: {
                   1040:        register char c1, c2;           /* s1[] may be shorter s2[] or
                   1041:                                                                                  their length may be equal */
                   1042: 
                   1043:        while (max--)
                   1044:        { 
                   1045:                c1 = *s1++;
                   1046:                c2 = *s2++;
                   1047: 
                   1048:                if ( c1 != c2 )
                   1049:                {       
                   1050:                        if ( c1 < c2 )  return -1;
                   1051:                        else                    return  1;
                   1052:                }
                   1053: 
                   1054:                if(c1 == 0)             return  0;
                   1055:        }
                   1056:        
                   1057:        return  0;
                   1058: }
                   1059: 
                   1060: 
                   1061: 
                   1062: /*-------------------------------------------------------------------------------
                   1063: 
                   1064: Routine:       PStrNCmp        -       Compare two char strings.
                   1065: 
                   1066: Function:      Compare the first N characters of two char strings.
                   1067: 
                   1068: 
                   1069: Input:         s1              - pointer to Pascal string.
                   1070:                        s2              - pointer to Pascal string.
                   1071:                        max             - N chars to compare
                   1072: 
                   1073:                        
                   1074: Result:                -1              - s1 < s2
                   1075:                         0              - s1 = s2
                   1076:                         1              - s1 > s2
                   1077: -------------------------------------------------------------------------------*/
                   1078: 
                   1079: short  PStrNCmp        (ConstStr255Param str1, ConstStr255Param str2, UInt32   max)
                   1080: {
                   1081:        char c1, c2;            
                   1082:        UInt8 l1, l2;
                   1083:        char *s1,*s2;
                   1084: 
                   1085:        l1 = str1[0]; s1 = (char *)str1; s1++;
                   1086:        l2 = str2[0]; s2 = (char *)str2; s2++;
                   1087:        
                   1088:        if ((l1 == 0) && (l2 == 0))
                   1089:                return  0;
                   1090:                
                   1091:        while (max && l1 && l2)
                   1092:        { 
                   1093:                max--; l1--; l2--;
                   1094:                c1 = *s1++;
                   1095:                c2 = *s2++;
                   1096: 
                   1097:                if ( c1 != c2 )
                   1098:                {       
                   1099:                        if ( c1 < c2 )  return -1;
                   1100:                        else                    return  1;
                   1101:                }
                   1102:        }
                   1103:        
                   1104:        if ((max == 0) || ((l1 == 0) && (l2 == 0)))
                   1105:                return  0;
                   1106:                
                   1107:        if (l1)
                   1108:                return 1;
                   1109:        return -1;
                   1110: }
                   1111: 
                   1112: 
                   1113: /*-------------------------------------------------------------------------------
                   1114: 
                   1115: Routine:       CStrLen -       returns length of char string in characters.
                   1116: 
                   1117: Function:      Returns the length of char string 'src' in characters. This does
                   1118:                        NOT include the terminating null character.
                   1119: 
                   1120: 
                   1121: Input:         src             - pointer to a char string.
                   1122:                        
                   1123: Result:                number of characters in char string 'src'
                   1124: 
                   1125: -------------------------------------------------------------------------------*/
                   1126: 
                   1127: UInt32 CStrLen (const char     *src)
                   1128: {
                   1129:        UInt32 len = 0;
                   1130:        
                   1131:        while (*src++)
                   1132:                ++len;
                   1133:                
                   1134:        return len;
                   1135: }
                   1136: 
                   1137: /*-------------------------------------------------------------------------------
                   1138: 
                   1139: Routine:       PStrLen -       returns length of Pascal string in characters.
                   1140: 
                   1141: Function:      Returns the length of Pascal string 'src' in characters.
                   1142: 
                   1143: Input:         src             - pointer to a Pascal string.
                   1144:                        
                   1145: Result:                number of characters in Pascal string 'src'
                   1146: 
                   1147: -------------------------------------------------------------------------------*/
                   1148: 
                   1149: UInt32 PStrLen (ConstStr255Param src)
                   1150: {
                   1151:        UInt8   strlen;
                   1152:        char    *s = (char *)src;
                   1153:        
                   1154:        strlen = *s;
                   1155:        
                   1156:        return (UInt32)strlen;
                   1157: }
                   1158: 
                   1159: 
                   1160: /////////////////////////////////////////////////////////////////////////////////
                   1161: //
                   1162: //     Software Interrupts
                   1163: //
                   1164: //
                   1165: 
                   1166: OSErr InitSwis (void)
                   1167: {
                   1168:        long    i;
                   1169:        Swi_Information *swi;
                   1170:        
                   1171:        PBQueueCreate (&CreatedSwis);
                   1172:        
                   1173:        PBQueueCreate (&AvailableSwis);
                   1174:        
                   1175:        AllSwis = PoolAllocateResident( sizeof(Swi_Information) * N_SWIS, true );
                   1176:        if ( !AllSwis )
                   1177:                return memFullErr;
                   1178:        
                   1179:        swi = AllSwis;  
                   1180:        for (i=0;i<N_SWIS;i++)
                   1181:        {
                   1182:                // swi->Name = 'SWI!';
                   1183:                PBEnqueue ( &swi->Link, AvailableSwis);
                   1184:                swi++;
                   1185:        }
                   1186:                
                   1187:        return noErr;
                   1188: }
                   1189: 
                   1190: /*-------------------------------------------------------------------------------
                   1191: 
                   1192: Routine:       CurrentTaskID   -       Returns ID of the Current Task. (@NON-Int Lvl)
                   1193: 
                   1194: -------------------------------------------------------------------------------*/
                   1195: 
                   1196: TaskID CurrentTaskID (void)
                   1197: {
                   1198:        if (CurrentExecutionLevel() != kTaskLevel)
                   1199:        {
                   1200:                // SysDebugStr ((StringPtr)"\pCurrentTaskID not called at Task Level!");
                   1201:                return (TaskID)-1;
                   1202:        }
                   1203:        
                   1204:        return (TaskID)0;
                   1205: }
                   1206: 
                   1207: /*-------------------------------------------------------------------------------
                   1208: 
                   1209: Routine:       DelayFor        -       Block Current Task for a Duration. (@NON-Int Lvl)
                   1210: 
                   1211: -------------------------------------------------------------------------------*/
                   1212: /*naga
                   1213: OSStatus DelayFor ( Duration expirationTime )
                   1214: {
                   1215:        AbsoluteTime    abt;
                   1216:        Nanoseconds             nano;
                   1217:        SInt64                  divisor;
                   1218:        SInt64                  remainder;
                   1219:        SInt64                  numTicks;
                   1220:        unsigned long   finalTicks;
                   1221:        
                   1222:        if (CurrentExecutionLevel() != kTaskLevel)
                   1223:        {
                   1224:                // SysDebugStr ((StringPtr)"\pDelayFor not called at Task Level!");
                   1225:                return -1;
                   1226:        }
                   1227:        
                   1228:        abt             = DurationToAbsolute    ( expirationTime );
                   1229:        nano    = AbsoluteToNanoseconds ( abt );
                   1230:        
                   1231:        divisor.hi = 0;
                   1232:        divisor.lo = 16666666;
                   1233: 
                   1234:        numTicks = S64Divide( *(SInt64*)(&nano), divisor, &remainder );
                   1235:        
                   1236:        Delay ( numTicks.lo, &finalTicks );
                   1237:        
                   1238:        return noErr;
                   1239: }
                   1240: naga */
                   1241: #if 0   //naga
                   1242: /*-------------------------------------------------------------------------------
                   1243: 
                   1244: Routine:       DelayForHardware        -       Delay for an AbsoluteTime. (Int Lvl)
                   1245: 
                   1246: -------------------------------------------------------------------------------*/
                   1247: 
                   1248: OSStatus DelayForHardware ( AbsoluteTime absoluteTime )
                   1249: {
                   1250:        // Obtain the NanoKernel's private pointer to the ProcessorInfo structure.
                   1251:        // This pointer is contained in the location defined by the private enum
                   1252:        // 'ProcessorInfoPtr'
                   1253:        NKProcessorInfo *processorInfo = *((NKProcessorInfo **) nkProcessorInfoPtr);
                   1254: 
                   1255:        if (gDelayForHdwrProc == nil)
                   1256:        {
                   1257:                
                   1258:                // First Time Initialization
                   1259:                
                   1260:                if ((processorInfo->ProcessorVersionReg >> 16) == 0x0001)
                   1261:                {
                   1262:                        // PowerPC 601 Chip (Use RTC, not TimeBase)
                   1263:                        
                   1264:                        gDelayForHdwrProc = DelayForHardware601;
                   1265:                }
                   1266:                else
                   1267:                {
                   1268:                        // Non-PowerPC 601 (Use TimeBase, not RTC)
                   1269:                        
                   1270:                        gDelayForHdwrProc = DelayForHardwarePPC;
                   1271:                }
                   1272:        }
                   1273:        
                   1274:        return gDelayForHdwrProc(absoluteTime);
                   1275: }
                   1276: #endif
                   1277: /*-------------------------------------------------------------------------------
                   1278: 
                   1279: Routine:       CreateSoftwareInterrupt -       Makes a SWI. (@any exec-Lvl)
                   1280: 
                   1281: -------------------------------------------------------------------------------*/
                   1282: 
                   1283: OSStatus CreateSoftwareInterrupt       (       SoftwareInterruptHandler        theHandler,
                   1284:                                                                                TaskID                                          theTask,
                   1285:                                                                                void                    *                       theParameter,
                   1286:                                                                                Boolean                                         persistent,
                   1287:                                                                                SoftwareInterruptID *           theSoftwareInterrupt)
                   1288: {
                   1289:        Swi_Info        aSwi;
                   1290:        
                   1291:        if ( PBDequeueFirst (AvailableSwis, (QElemPtr *)&aSwi) != noErr )
                   1292:                return paramErr;
                   1293:                
                   1294:        aSwi -> Handler         = theHandler;
                   1295:        aSwi -> The_Id          = (SoftwareInterruptID)aSwi;
                   1296:        aSwi -> The_Task        = theTask;
                   1297:        aSwi -> Temporary       = !persistent;
                   1298:        aSwi -> Sent            = false;
                   1299:        aSwi -> P1                      = (void *)theParameter;
                   1300:        
                   1301:        if (theSoftwareInterrupt != nil)
                   1302:                *theSoftwareInterrupt = (SoftwareInterruptID)aSwi;
                   1303:                
                   1304:        PBEnqueue ( &aSwi->Link, CreatedSwis);
                   1305:        
                   1306:        return noErr;
                   1307: }
                   1308: 
                   1309: 
                   1310: /*-------------------------------------------------------------------------------
                   1311: 
                   1312: Routine:       SendSoftwareInterrupt   -       Runs a SWI. (@any exec-Lvl)
                   1313: 
                   1314: -------------------------------------------------------------------------------*/
                   1315: 
                   1316: OSStatus SendSoftwareInterrupt         (       SoftwareInterruptID                     theSoftwareInterrupt,
                   1317:                                                                                void                    *                       theParameter)
                   1318: {
                   1319:        Swi_Info        aSwi;
                   1320:        SoftwareInterruptHandler handler;
                   1321:        Boolean         temp;
                   1322:        void            *p1;
                   1323:        OSErr           Result = PBDequeue ( (QElemPtr)theSoftwareInterrupt, CreatedSwis);
                   1324:        
                   1325:        if (Result != noErr)
                   1326:                return (OSStatus)Result;
                   1327:                
                   1328:        aSwi = (Swi_Info)theSoftwareInterrupt;
                   1329:        
                   1330:        // Store away swi info in locals.
                   1331:        handler = aSwi -> Handler;
                   1332:        p1              = aSwi -> P1;
                   1333:        temp    = aSwi -> Temporary;
                   1334:        
                   1335:        // Return temp swis now.
                   1336:        if ( temp )
                   1337:                PBEnqueue ( &aSwi->Link, AvailableSwis );
                   1338:                
                   1339:        // Call the handler
                   1340:        (*handler) (p1, (void *)theParameter);
                   1341:        
                   1342:        // Return persistant swis later.
                   1343:        if ( !temp )
                   1344:                PBEnqueue ( &aSwi->Link, CreatedSwis );
                   1345:                
                   1346:        return noErr;
                   1347: }
                   1348: 
                   1349: /*-------------------------------------------------------------------------------
                   1350: 
                   1351: Routine:       DeleteSoftwareInterrupt -       Destroys a SWI. (@any exec-Lvl)
                   1352: 
                   1353: -------------------------------------------------------------------------------*/
                   1354: 
                   1355: OSStatus DeleteSoftwareInterrupt       ( SoftwareInterruptID theSoftwareInterrupt )
                   1356: {
                   1357:        Swi_Info        aSwi;
                   1358:        OSErr           Result = PBDequeue ( (QElemPtr)theSoftwareInterrupt, CreatedSwis);
                   1359: 
                   1360:        if (Result != noErr)
                   1361:                return (OSStatus)Result;
                   1362:                
                   1363:        aSwi = (Swi_Info)theSoftwareInterrupt;
                   1364:        
                   1365:        PBEnqueue ( &aSwi->Link, AvailableSwis );
                   1366:        
                   1367:        return noErr;
                   1368: }
                   1369: 
                   1370: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.