Windows上でJWASM(フリーのMASM6互換アセンブラ)と98エミュを使ってのプログラム作成に関するエトセトラ。また、PC-98プログラミング関係の書籍紹介とか自作ソフトの進捗とかも。

小ネタとかメモ

フレーム待ちについて
VSYNC信号を待たないとフレーム待ちできません。
結果、スクロールが最後まで吹っ飛んだりします。

VSYNCがOFFまで待つ→ONまで待つ→画面設定や表示処理、表裏切り替えなど が基本のようです。
ONなら表示、にしたりするとVSYNC信号の終わりがけでも表示が始まるので、処理が終わりきらないことがあったりします。

具体的なコードはPC9801スーパーテクニックが詳しいです。
一応IOポートはA0Hで、20HだったらVSYNCがOFFだったはずです。
よほどのことがない限りはこれで十分なので、割り込みをフックするのはレアケースかと。

ループ中に一時停止する簡便な方法
画像表示のデバッグでバグが出るタイミングを知るのに使ったりする小ネタ。
push ax
mov ah,08h
int 21h
pop ax
これを入れるとキー入力待ちになって止まります。
押しっぱなしにすると(処理落ちしつつ)動き続けるので処理が長い場合もOK。
DOSの割り込みを使っているのでお手軽簡単です。
特定のループで止める場合はPROC化してローカル変数を使ってcmpするとかすればいいでしょう。


MACROとPROC
MACROはそこに展開されてPROCは呼び出し、と言うのは常識でしょう。
また、call→retの分だけMACROは高速ですが、容量を食うのが欠点とされています。
また、ローカルラベルの指定は出来ますが、展開されるので明示的にローカル変数が使えないのも欠点かもしれません。

古いMASMの場合、MACROは引数指定ができましたが、PROCはレジスタを経由させる必要があったそうで、その分MACROが便利だったそうです。
しかし、MASM6やJWASMではinvokeで引数を付けたPROCを呼び出せるので、この利点は薄くなっています。
さらにローカル変数が使えたり、定義で指定したレジスタを自動で保存する機能もあったりします。
これらは他言語での呼び出し用関数を作るのに特に便利な機能ですが、アセンブリでも楽になります。

と言うことで、私も便利なPROCを使っていることがほとんどなのですが、INVOKEには幾つか問題点があります。
PROC内でinvokeするとローカル変数でバグることがある
ローカル変数はスタック上に自動指定して変換されているらしいので、invokeした引数を使ってさらにinvokeとかをするとスタックのベース指定が変わって正常な引数が指定できずバグります。

invokeの引数もスタックに積まれる
自動で積んで出すコードが挿入されるので見た目はシンプルになりますが、処理は増えます。
容量も単純なPROCより大きくなります。

ローカル変数や引数の使い所に注意
ローカル変数や引数の呼び出しは[BP+整数]で呼び出されるらしいので、単純なレジスタのやり取りより数バイト大きいです。
△砲眤腓く関わる所ですが、386以前のCPUではレジスタ間のmovよりメモリが関わるmovの方が遅い(プログラマーズbibleより)ので、処理速度もかなり遅くなります。
画像表示でinvoke内invokeをやると、エミュでのデバッグ時ですらフレームが遅れて没になることがある位です。

以上の問題点から、シューティングゲームなど速度が十分に必要な場合は「レジスタやスタックに引数+単純なPROC」かMACRO、MACROで引数をレジスタに入れてPROC呼び出し、などを使うべきでしょう。
ただし、スタックに積む場合はprocで更に積まれるのに注意が必要かもですが。
単純な画像の表示などではinvokeで大抵は事足りるので、私のような素人にはあまり縁がないです。


追記
最近invokeをMACROを併用したPROCに書き換える実験をしました。
多くの場合は軽量化できましたが、任意の画像表示の場合は大きくなったりもしました。
とりあえずDSにデータ読み込みと任意のセグメントにデータ読み込み、のような初期化が微妙に違うけど中身はほぼ共通といった場合には共通Proc+MACRO初期化はかなり有効でした。
きちんとマシン語の利点を生かすのなら、使い分けが必要なんでしょう。

この項の内容は自分の経験とMASM ver.6.0ハンディマニュアルの内容を元にしています。

MACROでまとめる
メインのプログラムのコードを書いていると、DSの内容が増えたりPROCを呼び出す間の処理とかで行数が増えすぎて、コードが見づらくなる事があります。
そこでそういう所をMACROにしてしまって別のファイルにし、先頭でincludeして必要な所にマクロ名を一行書いてやるだけにすると見やすくなる、というだけの小ネタです。
ただし、スタックとかレジスタの内容が意味不明にならないように注意しましょう。

シューティングの当たり判定アイディアメモ
自機や背景では画像プレーン0から2だけの8色を使い、敵や弾にはプレーン3を含めると、自機の表示位置付近のプレーン4と透過フラグでandをとって0じゃなかったらヒット、とか軽いんじゃないかと思いました。
自分の弾と敵の当たり判定も他のプレーンで同じことをできるように画像を作ればいける気がします。
例によってアイディアメモなので、実用的ではないかもしれませんが、とりあえずメモ。

Menu

管理人/副管理人のみ編集できます