午前様になってしまいました。昨日はDOTRAIN用のマシン語モニタを制作していました!
Dコマンドでメモリを見ることができます。D003hならばDD003と入力します。
カーソルの上でアドレスがさがり、カーソルの下でアドレスがあがります。
Sコマンドでメモリを書きます。カーソルがあるアドレスを書きます。
このように間違えて書き込んでも前のデータが表示されます。
03asFFではなくて、FFas03が正しい表記ですが、このようにして書き込んだ場合のメッセージを表示します。
なにも書き込まないで、Enterの場合はアドレスが+1上がります。さらに^でアドレスが下がります。
DとSコマンド不自由なくメモリを操作できると思います。
マシン語プログラムはこのアドレスにデータを書き込みます。
なお、マシン語の実行開始アドレスの指定はDEFUSR、実行はA=USRとセーブはBSAVE、ロードはBLOAD
どちらもBASICでできるので、ここでは機能として加えていません。
BコマンドでBASICプログラムを終了とかなりシンプルですが、
これはマシン語プログラムを置けるようにするためです。
やはり、自力でやるより裏RAMにモニタアセンブラを置いたSUPER-Xを使った方がグッとラクですね。
また、MSX-DOSがあれば便利ですが、どちらもない環境で考えてみるとかなり使いにくいです。
結局、DATA文でダンプしたものをRAMに読み込む方式でやります。
現在はDOTRAINのマシン語ソースプログラムを作成中です。
「どのようなプログラムがマシン語になるの?」と、言えば
1段階目、座標指定と移動値を入れるとスルッと動く
2段階目、指定された座標の色を調べる
3段階目、複数のスプライトを同時に動かす
4段階目、指定された色にならって移動する
IFのような条件処理、+1,-1の加減処理、X,Y座標指定、POINT関数、
PUTSPRITEなど多いです。
特に条件処理はBASICでは遅いので、どのくらい速くなるのか気になるところです。
それでは1段階目をはじめていきます。
BASICでSCREENとスプライトを定義したVRAMデータをBLOADした設定にして、
マシン語プログラムを実行するとスプライトを表示できるようにします。
前回のソースを使ってみると
;X
LD HL,7600h
LD A,100
CALL VRM_W
をINC A(+1)、Aレジスタを+1加算するに
;X
LD HL,7600h
INC A
CALL VRM_W
書き変えてループさせるとスルッと右へスプライトが動きます。
LOOP: LD HL,7600h
INC A
CALL VRM_W
CP FFh
JP NZ,LOOP
RET
このようにAレジスタを加算してCPで比較します。
AレジスタがFFhならばZフラグが1でRETで終わります。
FFhは255ですから、画面の右まで移動したら実行完了となります。
では整理しますと
・VRAMに書き込む:NWRVRM(0177H)
MSXテクニカルハンドブック p352参照。
BIOSを使うので、指定されたラベルに変えます。
NWRVRM EQU 0177h
;SPR-SET
;Y
LD HL,7600h
LD A,100
CALL NWRVRM
;X
LD HL,7601h
LD A,100
CALL NWRVRM
;Patturn #
LD HL,7602h
LD A,0
CALL NWRVRM
;Color
LD HL,7803h
LD A,15
CALL NWRVRM
LOOP: LD HL,7600h
INC A
CALL NWRVRM
CP FFh
JP NZ,LOOP
RET
これで動かすことができますが長いですね。そこで、初期座標までBSAVEしておけば
LOOP: LD HL,7600h
INC A
CALL NWRVRM
CP FFh
JP NZ,LOOP
RET
ソースプログラムはこれだけで動作します。(本当か?)
ウソです。まず、スプライトアトリビュートテーブルからX座標をAレジスタに書き込む処理が必要です。
擬似命令を外していますが、逆アセンブラならばNWRVRM EQU 0177h
ですから、EQUはイコール、0177hに変えてCALL 0177hとします。
LOOPのラベルの場所のアドレスを書き、それがJP NZ,<アドレス>になります。
VRAMのデータのセーブは画面の保存をすることができますから、
次回動かすときはその画面の状態から始めることができます。
ということはBASICを使うとマシン語というのは大袈裟なものではありませんね。
たった数行で実行できるものです。さらにマシン語ダンプリスト?にすれば13バイト程度です。(たぶん)
D000: 21 00 76 3C CD 77 01 FE FF C2 00 D0 C9
ですが、LD A,0Ahを加えてみると
D000:3E 0A 21 05 76 3C CD 77 01 FE FF C2 02 D0 C9
この方が親切ですね、最初にAレジスタの設定を入れます。
BASICではないのでAレジスタの値は変わります。
するとLOOPのアドレスが変わりますから、C2 02 D0になっています。
ダンプができました!
たとえば違うスプライト番号を移動したい場合は7600hを7605hにすればよいです。
マシン語モニタで21 00 76を21 04 76にします。
このようにマシン語モニタではプログラムを部分的に変える場合に使います。
実行してみると速すぎて見えません。リニアのように速いです。
これに条件処理が入るので、遅くはなりますが、かなり速い感じがする予感です。
また、メモリの読み書きだけのかなりシンプルなモニタができたので、
これをスタンドアロン版として、DM-SYSTEM2のマシン語モニタにしてみたいです。
DM-SYSTEM2を使用すると裏RAMになるので、残念ながらSUPER-Xは動作できません。
そこで専用のモニタが欲しい気がします。
もし、アセンブラのシステムを組むとするなら、この環境ですとメモリマッパ上になりそうです。
そうするとMSX-DOS2でMSXturboRか1chipMSX向けになりそうかな。
でもMSX2ユーザーは使えないので、やはりディスクアクセス方式になるのが現実でしょう。
★参考資料
マシン語適当講座その3
http://www.geocities.jp/fullmsx2/u-yan/msx-mac3.html