PalmOS 5.x Hack開発講座 第3回 「ARMHackの組みたて」

1.題材

 前回は、「テキスト入力フィールドの下線を点線ではなくて実線にしてしまう」m68kHackを組んでみたところまでお話しました

 今回は、いよいよARMHackを組んで見ましょう

 やっぱり、フォルダの構成を揃えておきますね 今回はcドライブのルートに[ARMHack]というフォルダを作成し、さらに[solidLineHack]というサブフォルダを作成して、これから記述するファイルを置くことにします [c:\ARMHack\solidLineHack] ついでにこのフォルダをマウントしておきましょう [mount -tf "c:\ARMHack" /ARMHack]

 もう一点、[YAHM Dev Info.]からSDKをダウンロードして、解凍したファイルの中から[SysTables.txt]と、[\include]と[\lib]の二つのフォルダを[c:\ARMHack]以下にコピーしておきます

2.今度はARMHack

2.1.リソース定義ファイル[*.rcp]の記述

 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)

 こちらもいっしょ

 あとはコンパイルを残すのみ あっというまです

3.shellコマンドリストの作成

 今回も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]というライブラリになります

 あとはいっしょ

 さあ、ビルドしてみましょう

4.ビルドしてみよう

 Cygwinを起動して、[cd /ARMHack/solidLineHack]とタイプしてディレクトリを移動します

 あとは何も考えず[sh compile.sh]でしたね

 ごそごそと何かやっているようだけど... 今回も、何も起こらないはずです

 ファイルの一覧を見てみましょう [ls]とタイプして...

 おお、無事に[solidLineHack-ARM.prc]がいましたね うまくいっているようです

5.試してみよう

 今回はシミュレータが使えないので、いきなり実機です

 まず、フルバックアップを取って、[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を使ってみましょうか

 第4回「CodeWarriorで組んでみる」

質問、感想などはPalmHackersSalonのBBSへ

T-Pilot sekino