PalmOS 5.x Hack開発講座 第3回 「ARMHackの組みたて」
前回は、「テキスト入力フィールドの下線を点線ではなくて実線にしてしまう」m68kHackを組んでみたところまでお話しました
今回は、いよいよARMHackを組んで見ましょう
やっぱり、フォルダの構成を揃えておきますね 今回はcドライブのルートに[ARMHack]というフォルダを作成し、さらに[solidLineHack]というサブフォルダを作成して、これから記述するファイルを置くことにします [c:\ARMHack\solidLineHack] ついでにこのフォルダをマウントしておきましょう [mount -tf "c:\ARMHack" /ARMHack]
もう一点、[YAHM Dev Info.]からSDKをダウンロードして、解凍したファイルの中から[SysTables.txt]と、[\include]と[\lib]の二つのフォルダを[c:\ARMHack]以下にコピーしておきます
PilRCに渡すリソース定義ファイル[*.rcp]を記述します 今回も[solidLineHack.rcp]としましょう
アプリケーション名[tAIN]とバージョン[tver]の記述
APPLICATIONICONNAME ID 3000 "solidLineHack-ARM" VERSION ID 1 "_ARM"
ここは、前回といっしょ
次、どのAPIをトラップするつもりであるかをHackマネージャに教えてあげるための[TRAP]リソースならぬ[TRA5]リソースの記述
前回と同じく一番目に[FldDrawField]を、二番目に[FldSetAttributes]をトラップすることとして、この順番で記述します
※今度はCoreTraps.hではなくて、[YAHM Dev Info.]に同梱されている[SysTables.txt]を参照し、上記二つのAPIのTrapNo.を調べてください
UITable 0x12C FldDrawField
UITable 0x1A4 FldSetAttributes
と書かれていますね メモメモ...と
では、書いてみましょう
HEX "TRA5" ID 1000 00 00 00 12 (←※) 00 00 01 0x2c 00 00 00 00 00 00 00 00 00 00 00 00 HEX "TRA5" ID 1001 00 00 00 12 (←※) 00 00 01 0xa4 00 00 00 00 00 00 00 00 00 00 00 00
そんなに難しくないと思いますが、ポイントをひとつ ※のところは「トラップするAPIがどんな分類に属しているか」を示しています HALであれば4、Systemであれば8、UIであれば12としてあげます
なにやら長くなってしまいましたが、リソース定義ファイルはこれだけ 簡単ですね
2.2.置き換え実行コード(APIの代わりに呼び出される実行コード)の記述
まずは一番目の[FldDrawField]の代わりに呼ばれるコードを書いてみましょう 先ほど記述した[TRA5]リソースのIDにあわせて[armc 1000]リソースとして作成しますので、[armc03e8.c]とします(03e8は16進数表記で、10進数に直すと1000)
では、書いていきます といいつつ、ほとんど一緒なので違うところだけ...
#include "../Include/palmos5.h"
と、
STANDALONE_CODE_RESOURCE_TYPESTR_ID("armc", RESID);
と... あれ、これだけですね 他のところは変えようがないですもの
一つ目の[palmos5.h]をインクルードしているのは、一部のAPIに変更が加わっているためで、変更が加わっているAPIを使用しないのであれば、もともとの[PalmOS.h]のままでもかまいません
もう一つのほうも見てみましょうか こちらは、二番目の[FldSetAttributes]の代わりに呼ばれるコードを書いてゆきます 先ほど記述した[TRA5]リソースのIDにあわせて、今度は[armc 1001]リソースとして作成しますので、[armc03e9.c]とします(03e9は16進数表記で、10進数に直すと1001)
こちらもいっしょ
あとはコンパイルを残すのみ あっというまです
今回もCygwinのshellコマンドリストを作成しましょう コンパイルするたびに、いちいちタイプしていては面倒ですから
ここでも、[compile.sh]として作成します このshellコマンドリストを実行するときは[sh compile.sh]とタイプすればOK
まず一行目
pilrc -q -ro solidLineHack.rcp
ここは前回と一緒
次 前回よりさらに長くなっていますが[armc03e8.c]と[armc03e9.c]をコンパイルして[armc 1000]および[armc 1001]リソースを作ってくださいとコンパイラにお願いする部分です 今回はARMコンパイラにお願いしましょうね
arm-palmos-gcc -Wall -Wno-multichar -fshort-enums -fpack-struct -O1 -DCRID=\'SolL\' -nostartfiles -D_ARM_HACK_ -c -o armc03e8.o armc03e8.c arm-palmos-gcc -nostartfiles -o armc03e8 armc03e8.o ../lib/libarmboot.a ../lib/libarmui.a arm-palmos-gcc -Wall -Wno-multichar -fshort-enums -fpack-struct -O1 -DCRID=\'SolL\' -nostartfiles -D_ARM_HACK_ -c -o armc03e9.o armc03e9.c arm-palmos-gcc -nostartfiles -o armc03e9 armc03e9.o ../lib/libarmboot.a ../lib/libarmui.a
基本的に前回と一緒 [libarmboot.a]と[libarmui.a]というライブラリをインクルードしていることが前回と違う点ですね
自分でHackを管理するのでなければ、このへんはあまり詳しく知らなくても問題ないので簡単に...
OS5では、API関数の型に変更は加わっていませんが、API関数の呼び出し方法が変更されました OS4以前は、MPUの[TRAP]命令による例外処理を利用してAPI呼び出しを行っていましたが、OS5では通常の関数呼び出しと同じ方法になりました 具体的には、「API関数のアドレスを取得してブランチ」ですね この部分の処理を記述してくれているのが[libarmboot.a]と[libarmui.a]というライブラリになります
あとはいっしょ
さあ、ビルドしてみましょう
Cygwinを起動して、[cd /ARMHack/solidLineHack]とタイプしてディレクトリを移動します
あとは何も考えず[sh compile.sh]でしたね
ごそごそと何かやっているようだけど... 今回も、何も起こらないはずです
ファイルの一覧を見てみましょう [ls]とタイプして...
おお、無事に[solidLineHack-ARM.prc]がいましたね うまくいっているようです
今回はシミュレータが使えないので、いきなり実機です
まず、フルバックアップを取って、[YAHM]と[solidLineHack-ARM.prc]をインストールして...と
[YAHM]を起動して、[solidLineHack-ARM]にチェックを入れて...
目をつむって、[Memo]を起動...
さあ、目を開けて見ましょうか
うまく行ったので、ARMHackのお話はここまで m68kHackとほとんど変わらなかったでしょう?
今回は、人にお話しするためにお行儀のよいコードで書いていますので、トラブルなくあっさりとm68kHackからARMHackに移行できてしまいました ただ、お行儀のよいコードばかりを書いているわけにも行きませんよね、遅いですしスマートではないですし...
例えば、構造体のメンバに直接アクセスしたい場合が出てくるでしょう この場合は注意が必要です 構造体の定義の部分に以下のような記述があった場合は、まず間違いなく変更が加わっています
WARNING! PalmSource, Inc. does not support or provide
backward compatibility for the FieldType
structure.
Never access its structure members directly, or your code may
break in future versions. Use the information below for debugging
purposes only.
この場合は、構造体のメンバがどうなっているのか調べてから使うようにしましょうね 具体的には、「構造体の先頭アドレスから何バイト目に目的のメンバが格納されているのか」ということです
もう一点、ビットフィールドの取り扱いについて、m68kコードとARMコードの双方で共有する場合メンバの並び順が逆になりますので注意
そうそう、大事なことを忘れていました m68kコードで使用しているAPIがARMコードで用意されていない場合があります 単に無くなっているものもありますし、別のAPIで置き換えられている場合もあります 場合によっては同じ名前でAPIが用意されているのに、呼び出されないAPIも存在します
メジャーなところでは[EvtGetEvent]はありませんし、[KeyGetState]は存在しますがm68kコード中で呼ばれてもPACEが[HALKeyGetState]のコールに変えてしまうので[KeyGetState]は呼ばれません
このあたり、全てを網羅するのは大変なので、必要に応じて探すことにしましょう 一応、何かの参考になるはずなので、いくつかのサンプルコードをダウンロードできるようにしておきました (オリジナルとして手を加えて公開する場合は、クリエータIDを必ず変更してくださいね)
次回はどうしましょう CodeWarriorを使ってみましょうか
質問、感想などはPalmHackersSalonのBBSへ