|
|
|||||||||
|
|||||||||
|
|
HW 30 - CFM-68K から ADBOp を呼び出す方法(1997 年 5 月 11日) Q: CFM-68K プロセスから ADBOp を呼び出すと、バスエラーでクラッシュします。どうしたらこの問題を解決できるでしょうか。 A: これは、CFM-68K の InterfaceLib ファイル内のグルーコードにまつわる既知の問題です。解決方法は、自分でグルーコード (下記に掲載) を用意し、68K トラップを直接呼び出すことです。以下に示すグルーコードを組み込むためには、わずかですが、プログラムに次のような変更が必要です。
PowerPC コードから 68K コードを呼び出すグルーコードの実装方法の詳細は、TECHNOTE 1127「失われたリンクを求めて」を参照してください。この問題は System Software 8.1 で確認されています。バグレポート番号は 2227159 です。
#include <Types.h>
#include <DeskBus.h>
#include <MixedMode.h>
// ADBOp を直接呼び出すのではなく、ターゲットアーキテクチャにしたがい、
// 正しい呼び出しを行う MyADBOp を呼び出す。CFM68K の場合、
// ADBOpBlock 構造体を設定し、上記の ADBGlue ルーチンを呼び出す。
// 通常の 68K と PowerPC の場合は、ADBOp を直接呼び出す。
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;
// 重要: このサンプルでは、adbOpBlock 構造体をスタック変数として
// 宣言している。通常、非同期呼び出しでスタックパラメータを使うのは
// よくないことだが、ここでは、ADBOp が構造体の内容をコピーするので、
// 非同期呼び出しの間ずっと構造体を存続させる必要はない。
// 注意: 完全を期すため、refCon 値を ADBOpBlock 構造体に設定している。
// このプログラムは、完了ルーチンが refCon およびデータバッファを
// プロセスのグローバル変数として参照することを仮定している。
// 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
}
----------- Rich Kubota
[ Technical Q&A's : Hardware (for Mac OS) : HW30 ] |
|