パレット切り替え
シーンが変わったとき(V-BLANK 発生時)に、全パレット(16色で計32バイト)を切り替えるルーチンをCで書いたら、実行時に次フレームに侵食するということを数日前に書いたが、今日試しに cc65 が吐き出したアセンブラソースを眺めて見て愕然とした。どういうわけか、この箇所だけ、かなり悲惨なコードを吐き出していた。仕方ないのでアセンブラで書き直すと・・・あら不思議・・・(笑)ついでなので、高速化が必要な所を根こそぎアセンブラ化しておこう。
画面の上下反転機能
LYNXにはハードウェアで画面の上下反転機能が搭載されている。なぜそのような機能が搭載されているかというと、欧米の人は左利きの人が多いらしく、それらの人向け用に、本体を逆さまにして使用できるようにした結果そうなったらしい。
画面反転をさせるには、I/O ポートの SPRSYS の特定のビットを High / Low に切り替えればよいのだが(実際にはそれだけではないのだが・・・)困ったことに SPRSYS と VIDDMA は、リード時とライト時の各ビットのマッピング内容が異なるため、同 I/O の特定のビットだけを操作したい場合に、直接 and や or をすることができない。ゆえに RAM上に1バイトの仲介ワークを用意して、そのワークに対してビット操作を行い、ワークの内容をポートに転送するということをしないと、他のビットにも影響を及ぼしてしまい、とんでもない動作をしてしまうことになってしまう。
余談ではあるが、X68000 の ADPCM 再生周波数の設定ポートも、OPMレジスタの LFO波形設定ポートと同列の8ビット長ポートに存在するライトオンリーのポートだったため、 Human68K で $9da.b を仲介ワークとしていたりしたのだが、つまり、それと同じことを再現しないといけない。
解読の結果、zero page に __sprsys と __viddma というワークが決め打ちされており、そこを介することで問題解決のはずだったが、これらのワークは絶対番地で決め打ちされているのではなく、コンパイル毎に $00CC〜$00FF の範囲内に動的に配置されるため、Cから zero page 上の動的ラベルを直接参照しなくてはならなくなり、その方法が見つからず困っていたのだが、ドキュメントを読み倒すことから、やっと解決に至った。
メモ
extern unsigned char _sprsys;
#pragma zpsym("_sprsys")
つかれた・・・