Macintosh Programming (7) - PPCと68K - 2000.Sep. またもモーダルダイアログです。しつこくて済みません。だけど今回は68Kだけで なく、PPCでもコンパイルできるソースを作ってみます。 注:ええと。後で出てくる例とソースがほとんど同じなので、このソースは割愛   します。後述するように5行追加しただけのソースをダウンロードできるように   する予定なので。 何回か書いているようにオリジナルなMacのCPU (68KならMPUと呼ぶはずだ。という、 覚えている人の方が少ないよーな突っ込みは却下)とPPCは互換性があります。 どういうことかというと、68KでコンパイルしたプログラムはPPCマシンでもそのまま 動作する。ということです。 68Kのプログラムで書かれている場合、PPCを68Kモードにして動かす。ということなの ですが、問題もあります。当方の文章能力でちゃんと説明できるかどうか不安ですが、 ま、やってみます。 +----------+ +----------+ | 68Kアプリ| API呼び出し | PPCなROM | | Alert();|--> PPCモードに変更 -->| Alert();| | |<-- 68Kモードに戻す <--| | +----------+ +----------+ fig.1 エミュレーション動作 ここまではお分かりですね。APIを呼び出せば、それがAPIであることはMacには分かり ますから、その時点でPPCに切り替えてやれば良いのです。 +----------+ +----------+ | PPCアプリ| API呼び出し | PPCなROM | | Alert();|---------------------->| Alert();| | |<----------------------| | +----------+ +----------+ fig.2 ネイティブ動作 こちらは純PPCアプリです。切り替えの必要はありません。当たり前ですね。 で、です。ROM内の(って、ROM内にあるかどうかの確認はしてませんが、ToolBox 関数なんかは、ROM内と思う) 例えばAlert()が呼び出された時、CPUは常にPPC モードで動作していることになります。 - 余談 - Win32のAPIに加え、Win16のAPIの全てをそっくりWindows95に搭載した某社とは 違うアプローチを取った訳ですね(^^;; #Windows9xってのは要はWin32のAPI + Win16のAPI + DOSのAPIと、3つのOSが  全て含まれている。という製品。だからばかでっかい。 #んで、Mac OS XはUnixと旧来のMac OSが2重に載っかってるんですね。う〜む。  歴史は繰り返す?最低でも128Mなメモリが必要だと?勘弁してくれぇ…… #そーいや大概のLinuxデストリビューションにはKDEとGnomeが載ってますな。  でもあっちはどっちもX Windowの上で動くアプリケーションであるからして……。  いかん。ただでさえボロが出ている(出そう、とはもはや書けない)のに  ここで止めないとますます恥をかいてしまうぞ(手遅れかも)。 - 余談終わり - さて。ここで問題になるのはAlert()ってAPIにはフィルタを指定できる。という ことです。Alert(128, nil);の、nilの所に独自のフィルタ関数を指定できるって 実例は前にやりました。 つまり、PPCにスイッチされたCPUがフィルタ関数を実行する時、その関数は PPCなのか、68Kなのか?ということです。 #実行してすっ飛べば間違ったことが分かる(*1)って?あのねぇ。んなことを  やったら特権モードで動作しているMac OSは一発でフリーズして終わりに  なってしまいますぞ。  コードの先頭を見れば。。。って?おあいにく。私は6809/Z-80/68000/Z-8000/  8086のどのCPUで実行しても正しく動くプログラムを見たことあります。まぁ当時  Z-8000で動くパソコンはありませんでしたが、MZ-2000/X-1/FM-8/FM-7/PC-9801/  PC-8801のどのマシンに突っ込んでブートさせても正常動作する。というFDが  存在してました(X68000は所有者がいなかったので……)。  MZ-2000系は最初に読むセクタが他のマシンと異なってましたけど、他のは  同じセクタをブートローダとして読むのです(正確に言うとFM系はBasicモード  とそうでない場合は違ったけど、そのFDはどっちのモードでもブートしました  から、結局は異なるCPUでも大丈夫ってことで、大意は変わりません)。 おとと。また余談に流れた。で、ですよ。Apple社の回答はPPCの場合はフィルタ 関数にソースレベルで特別な細工を入れる。というものでした。 「ユニバーサルポインタ」の導入です。 68Kの場合: pascal hoge(); foo() { Alert(128, hoge); } PPCの場合: ModalFilterUPP Hoge; pascal hoge(); Hoge = NewModalFilterProc(hoge); foo() { Alert(128, Hoge); } #「hoge」とか「Hoge」は好きな名前で良い。ユーザが決める さて。1つのソースでどっちもコンパイルできるように、ちょっと#defineを探して みましょうか……。ええとCInterfacesの下をごそごそ。を、ConditionalMacros.h ですな。そこを見るとTARGET_CPU_PPCとTARGET_CPU_68Kが手頃そう。 #他にも一杯定義されてるので一度は見ること! …ほう。色々な他社製コンパイラ、gccやVC++、X86やSparc、Alphaといった定義も あるぞ。そーゆーCPUで動くバージョンもあるのか?>Mac OS でもMac、Win32、unixって定義は(最初のはともかく、後2つは)何時使うんだ? んげ。 #elif defined(applec) && !defined(__SC__) /* MPW C compiler from Apple Computer, Inc. << WARNING: Unsupported Compiler >> */ って、他人事のよーに自社製コンパイラをシカトしないでもらえます?(;_;)>Apple MPW C++の方はサポート対象のようですが。。。ってあれ? #elif defined(__SC__) && (defined(MPW_CPLUS || defined(MPW_C))) /* SC[pp] compiler from Apple Computer, Inc. */ だなぁ。どーゆーこと?昔のMPWのCはサポートしないが、今のMPWのC/C++はサポート 対象ってこと?よく分かりません(過去の経緯を知らない新参者はこんな場合に 判断に困ってしまう)。 …ということで。。。では実例、いってみましょうか(見なかったフリ、見なかったフリ)。 1. モーダルダイアログリソースを取り出し 2. 表示する前にちょっと化粧直しをして、ダイアログを出す 3. イベント待ち。表示中に起きる細かいことはOSがやってくれるのでユーザは気にする   必要はない。が、一部は手伝ってやらないといけない(フィルタが必要な理由) 4. ユーザがダイアログにちょっかいかけると戻ってくるので、必要なアクションを   取る 5. 何か問題あれば3に戻って、ユーザの次のアクションを待つ 前のモーダルダイアログでは余りに例が簡単過ぎて良く分からなかったかもしれ ませんが、モーダルダイアログの(多分)典型的処理はこのようになります。 モーダルダイアログは他のウィンドウの操作をユーザに許しません。自アプリの 他のウィンドウはもちろん、他のアプリに切り替えることもできません。 逆に言えば、自分のウィンドウだけの世話をすれば良いのです。 …モードレスなウィンドウ(ダイアログ)の説明を未だしてませんので、ふ〜ん。 とか思うだけでしょうが、本番はこれからなのです(笑) (*1) Windows9xではわざと実行してすっ飛んだ所を捕まえて処理。ということを  やっていたりする。が、これはまともにスイッチするよりCPUの例外をトラップ  した方が高速である。というIntelなCPUの事情による。詳細は省略。  ちなみに、286をターゲットにしたOS/2開発部隊のIBM技術者が286は「脳死してる」  と嘆いたのは公然の事実。リアルモードへの切り替えがCPU Resetしかないとは  何事だ?という訳。その反省からか386は仮想86モードってのが追加されましたが、  386ネイティブではSuspend/Resumeがまともにできないではないかっ!とか  某社に噛み付かれて386/SL以降ではSMI割り込みを追加したとかゆー噂話もあったり  します。  #風の噂なので、つっこまれても困りますけどね んで、肝心のコンパイル方法なのですが、MPWのBuile->Create Build Commandsで 68K/PPC/Fatを指定してメークファイルを作ればOK。同じソースでちゃんとそれぞれ の実行ファイルができるように良きに計らってくれます。 (EOF)