TI-84 Plus CEでプログラミング!

f:id:PocketGriffon:20201120182718j:plain

Twitterに動画を投稿したが、某ゲームの背景を表示させてみた!

 

きっと見た人の90%は、あの音楽を口ずさんだのではないだろーかw

 

今回のこのプログラムは、TI-84 Plus CE(以降84PCE)でコードを書いてみたかったのと、eZ80である程度まとまったプログラミングをしてみたかっただけだ。

 …というわけで、これからゲームとして膨らませていく感じではない(^^;

期待させてごめんね!!

 

せっかくプログラミングしてみたので、84PCEでのプログラミングの注意点とか、eZ80での注意点などなどをご紹介してみたい。

 

TI-84 Plus CEで実行させるために

実行させるための方法は前回のブログに書いておいたけれども、制限がいくつかあった。

まず84PCEへ送り込めるファイルサイズは、どうやら64KBが最大のようだ。

つまり64KBの中に全てのデータとプログラムその他を詰め込まないといけない。別のマシンのように2段階ロードが出来るかどうかも分からない。同時にあれこれするのは大変なので、今回は64KBに納める方向で頑張ってみることにした。

 

今回表示させようとしている絵は、たぶんみなさんご存じだと思う。

元のゲームは1983年に稼働したゲームだ。当時のROMサイズを考えたら相当小さいデータとして格納されていたんだと思うけれども…今も同じデータフォーマットで持つわけにもいかない。なにせ84PCE…というかeZ80がどのくらいのパワーがあるのか未知数でしかないので、出来るだけVRAMの構造とデータを合わせておきたい。

 

84PCE自体、普段は16bpp表示となっている。このサイズで65536色も出たら表現力としては十分だ!画面サイズが320x240ドットとなっているのでVRAMのサイズは320x240x2で150KB!ひえぇ…(@_@; 

 え?!一度にロード出来るサイズは64KBなのに、VRAMが150KBあるのか…うむむ…なるほどいろいろと納得したw

 

その後、いろいろと調べてみたところ、どうやらVRAMのサイズが半分になるカラーインデックスモードが存在するらしい。これは…いきなりユーザープログラムで使って良いのかな…操作も含めて実験が必要だ。

f:id:PocketGriffon:20201120185248j:plain

ちなみに上記のBLUE、REDの位置が逆になっていた。どうやらこの2つを入れ替えるビットが存在していて、それが立っているらしい。アタマの中で勝手に「RGB」と思い込んでコンバータその他を書いてしまった後だったので、もうこれはそのまま行く事にしたw

 

ところで、84PCEは最大で48MHz動作が出来るらしい…普段は電池を持たせるためにそこまでの速度はださないんだろうけれども…でも任意で48MHzに出来るのかしら…。

Boot Callに_boot_Set48MHzModeなんてのがあるのだけれども、呼び出し方も関数の意味も分からず。これは今回は試すチャンスなさそうだなー(T-T)

 

マップデータの格納方法は…

これはもう今回の趣旨と外れてしまうため、詳しくは説明しない。

さらっと言うのであれば、マップ全体を8x8ドットで分割し、同じキャラクタは1つにまとめる等して容量を減らす方向で頑張っている。最終的にはキャラクタ、スクリーン、パレットの3つデータを保持した。

それでもマップ全体をメモリにいれる事は出来ず、実は見えているマップ以外のキャラクタやスクリーンはメモリに入っていない。別にナスカの地上絵を見せたくてココを表示させているわけではなく、メモリの都合上ココしか表示出来なかっただけだw

 

eZ80有象無象

私的な今回の目的は、やはりeZ80でプログラムをしてみたい!に尽きる。

作り始める前は「Z80の上位互換な感じでしょ?R800みたいな?」という感覚でしか無かったのだが、作っていくとその考えは大きく間違っていたと気が付く事に…(^^;;

 

レジスタペアのコピー

気が付いてからも何度も間違えてしまう代表格がコレ。

例えばHLレジスタをDEレジスターにコピー(交換じゃない)したい時、

    LD D,H

    LD E,L

って普通に書きますよね。Z80ではメモリ的にも速度的にも良いはず。

だけどコレ、eZ80ではうまくいかない。

レジスタペアが24bitに拡張されているのが主な理由なのだが、Hレジスタ、Lレジスタに加えて、さらに上位ビットのHLUレジスタというのが存在するらしい。「らしい」と付くのは、実際にそのレジスタへ直接アクセスする命令は存在しないので、呼び方も含めて良く分からないのだ。

仕方ないのでレジスタのコピーはPUSH/POPを使う事にした。

    PUSH HL

    POP DE

ちなみにeZ80のPUSH/POPは(ADLモード=1の時は)3バイトとなる。先ほどのHLUレジスタも含めて更新されるので安心だ。

 

同じような理由で、レジスタペアを確実に0に初期化するために、0でのロードが増えるのも仕方が無い。

    LD HL,0 ← HLUも含めて0クリアしたい

 

デバッガもない状態なのでバグが出たらコードを想像で追っていくしか無いが、記憶の片隅にもないレジスタの事でバグが出ると、ホントに手に負えない(^^;;

 

*インデックスレジスタが意外に便利

IX、IYレジスタ、なぜかZ80ユーザーからも敬遠されがちな気がする。私はワリと好きで積極的とは言わないけれども便利に使いたい人。

良く雑誌で見かけたのが「インデックスレジスタは遅くなるので使いませんでした」って記述。いつも「ええ?!そうなの?」と思ってました。だって使いどころをきちんとすれば、速度に勝るものがあるよ??

 

eZ80ではインデックスレジスタ周りの命令もいくつか新設されていて、とりわけ便利だなーて思ったのがコレ。実行速度はなんと驚きの6サイクル。

    LD HL,(IX+0)

Z80でも2命令で同じことが出来る。でも実行サイクルは38。

    LD L,(IX+0)

    LD H,(IX+1)

 

そして次がコレ。

    LEA IX,IX+n

Z80では見慣れない命令のLEA。でも他のCPUではワリと見覚えのある命令。

これがeZ80ならば使う事が出来る!

同じことは別のレジスタペアを用いれば実現は出来る。

    LD BC,nnnn

    ADD IX,BC

でもインデックスレジスタを使う時は、たいてい他のレジスタペアは埋まってる事が多いので、こういった単体のレジスタで加算が出来るのは本当に助かる(^^)

 

*でもインデックスレジスタは注意が必要…らしい?

インデックスレジスタを使っていて、プログラムの動作がとても不安定になる事が多々あった。プログラムの間違いが見つからず、もしや…と思ってIX,IYをPUSHして保護したらバグがピタっとおさまった。どうやらユーザープログラムでは壊してはいけなかったようだ。

特にIYレジスタについては取り扱い注意のようだ。

どこかのドキュメントに注意事項が書かれているのかも知れないけど、残念ながらそこまで探しきれてない(T-T)

 

*LDIRが速い?!

LDIRがふつーに速い気がする。回数が分かっているのならばLDIを並べるのが高速…がZ80では定石としてあったけれども、eZ80ではLDIRを積極的に利用するのが良い気がする。

実際、画面のスクロールはLDIRを繰り返し行っているが、見ての通りの速度が出てる。

 

*乗算命令は便利だけど…

eZ80に備わっている乗算命令。今回はキャラクタのアドレスを求める際に利用してる。

ただ…ちょっと面倒だったのは、8bit * 8bitの乗算だったら簡単なのだけれども、今回はキャラクタ数が256を超えていたため、16bit * 8bitが必要だった。

Boot Callに_Mult16By8というエントリがあったのだが、TI-84 Plusの時からあるエントリなので、もしかしたら乗算命令使ってないのかも??と思ってしまったので自前で書いたw

f:id:PocketGriffon:20201120212439j:plain

乗算自体は(A*H<<8)+(A*L)のありふれたアルゴリズムだけれども、ここでもHLU(16bit以降)に値を追いやる方法が分からないw 仕方ないのでADD HL,HLを大量に入れてみたが、後で思えばメモリを介した方がエレガントかも知れない。

こういう「存在するけどアクセスが自由に出来ない」レジスタはどうすればいいんだ…きっとeZ80に慣れた人ならではの定石があるんだろうなぁ…。

 

今回のプログラム

今回のプログラムというかパッケージは以下な感じになった。

・キャラクタデータ 44928バイト

・マップデータ 14848バイト

・カラーデータ 66バイト

・プログラムその他 502バイト

合計で60344バイトの8xpファイルが出来上がった。

このサイズのファイルを84PCEに転送するのはわずか数秒だ。

RS-232Cでちまちま転送していたのを普通にしている私に取ってみれば一瞬の出来事w

とても開発効率が良いと思った。

 

今回はハングアップするたびに84PCE裏面のリセットボタンを押すハメになった。途中、何度も押しすぎて「壊れないかな?」と心配になるほどにw

 

スクロール速度は、アーケード版に比べたら2〜3倍速いかもしれない。これはウェイトなしの速度となっている。この先、例えば自機を表示したりでっかいボスキャラを表示するには少し心許ない。

カラーインデックスモードを用いる事で、VRAMの半分が空いている。ここに圧縮されたデータを展開しておけば、もう少しあれこれ入るかも知れない。いやそれだったら2画面切り替えでちらつきをなくすか…。などなど、夢が広がってしまうハードなのは分かった(^^;;

 

eZ80は想像していた通りに速く、でも48MHzかと聞かれれば「多分違う」と思う。

私としては全体の速度を楽しむよりは、eZ80でのプログラミングとちまちました速度が楽しめれば十分だ!(^^)

それも今回のプログラミングで、一応は出来たかな…と思う。

 

ではまた次回!(^-^)ノ