|
|
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:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.