ADC Home > Reference Library > Technical Q&As > Legacy Documents > Mac OS 9 & Earlier >

Legacy Documentclose button

Important: This document is part of the Legacy section of the ADC Reference Library. This information should not be used for new development.

Making the ADBOp call from CFM-68K


Q: When I make the ADBOp call from a CFM-68K process, I crash with a bus error. How can I get around this problem?

A: This is a known issue with the glue code implemented in the CFM-68K InterfaceLib file. The solution is to implement your own glue code (presented below) to perform the call directly to the 68K trap. You will need to make some minor changes to your program to accommodate the glue code as documented here.

  1. Include the code below and change your call from ADBOp to MyADBOp.
  2. If you implement a completion routine, instead of accessing the register parameters directly (the optional refCon buffer and the data buffer), you'll need to access them as globals to the fragment. You can find a sample program demonstrating this code on the Developer CD - "SetLED."

For more information on implementing glue code for calls from PowerPC code to 68K code, refer to Technote 1127: "In Search of Missing Links." This problem was identified with System Software 8.1. The bug report number is 2227159.

#include <Types.h>
#include <DeskBus.h>
#include <MixedMode.h>
 
// Instead of making the ADBOp directly, call MyADBOp which makes the appropriate
// call depending on the target architecture. For CFM68K, the ADBOpBlock structure
// is filled in and the ADBGlue routine above is called. For regular 68K and PPC,
// the ADBOp call is made straightaway.
 
pascal OSErr MyADBOp(
Ptr refCon,
ADBServiceRoutineUPP compRout,
Ptr buffer,
short commandNum)
{
#if TARGET_CPU_68K && TARGET_RT_MAC_CFM
    ADBOpBlock adbOpBlock;
    adbOpBlock.dataBuffPtr = buffer;
    adbOpBlock.opServiceRtPtr = compRout;
    adbOpBlock.opDataAreaPtr = refCon;

    // Important note: In this sample, we declare the adbOpBlock structure
    // as a stack variable. Normally this is a bad practice to use a stack
    // parameter for any asynchronous call. ADBOp makes a copy of the
    // contents of the structure, so the structure does not need to exist
    // for the life of the asynchronous call.

    // Note that the refCon value is placed into the ADBOpBlock structure
    // for completeness. This program sample assumes that a completion
    // routine will access the refCon and the data buffer as globals
    // to the process, which is possible under CFM.
    return (OSErr) CallUniversalProc((UniversalProcPtr)NGetTrapAddress(0xA07C,0),
         kRegisterBased |
         RESULT_SIZE(SIZE_CODE(sizeof(OSErr))) |
        REGISTER_RESULT_LOCATION(kRegisterD0) |
        REGISTER_ROUTINE_PARAMETER(1,
        kRegisterA0,
        SIZE_CODE(sizeof(&gADBOpBlock)))  |
        REGISTER_ROUTINE_PARAMETER(2,
        kRegisterD0,
        SIZE_CODE(sizeof(commandNum))),
        &gADBOpBlock,
        commandNum);
#else // TARGET_CPU_68K && TARGET_RT_MAC_CFM
    return (ADBOp(refCon, compRout, buffer, commandNum));
#endif // TARGET_CPU_68K && TARGET_RT_MAC_CFM
}

[May 11 1998]


Did this document help you?
Yes: Tell us what works for you.
It’s good, but: Report typos, inaccuracies, and so forth.
It wasn’t helpful: Tell us what would have helped.