Making「ワイアノ」その1

Home PC-6001mkII Program etc

 このページでは、作成開始から画面表示までの過程を書いています。

Making「ワイアノ」 Top


2008/04/02:問題山積
 これまで4x4の格子だった表示を思いきって3x3まで減らす。4x4の時が直線40本に対し、3x3だと直線24本という事もあって、描画速度も速くなった。

 ここで、BASICからマシン語を呼び出してランダムに押す処理を加えてみる。いざ実行してみると...
ぎこちない。

 なにもせず表示だけ連続実行した場合は秒間10〜11コマ/秒くらいだったが、ランダムに押す処理を加えると秒間6〜7コマまで速度が下がった。実際に動きを見てわかったが、この程度の速度では話にならない。

 また、画面を消す処理も見せている事もあって、非常に画面がちらつく。この状態だと目にも悪いので、やはり2画面切り替え表示は必要だろう。

 その他、ときどき予想外のはみ出し表示になる。
画面

 このあたりもいつか解決しないとダメだが、とりあえず棚上げしておこう。

2008/04/05:ダブルバッファリング
 とりあえずちらつきをなんとかするべく、2画面切り替え表示を実装する。

 グラフィック画面を2つ使用して、一方の画面を表示している間にもう一方の画面を書きかえて、書き終わったら画面の表示を他方に切り替える、通称「ダブルバッファリング」と呼ばれる処理だ。

 と大層なことを言ったが、やった事は描画先アドレスを変更可能にした事と画面表示の切り替え処理を追加しただけだ。

 ただ、ちらつかなくなった事で、大きく見た目の印象が変わる。前回よりわずかだけ遅くなっているはずだが、ぎこちなさが若干減ったような錯覚を覚えるほどだ。

 という事で、今日はここまで。

2008/04/06:はみだし防止の微調整
 4/2で出ていたはみ出し処理だが、原因はわかっている。4点の座標の平均値を求める処理だ。

 X座標なら「(x1 + x2 + x3 + x4) / 4」という処理をマシン語で書いているのだが、速度重視のため計算途中の値も -128〜127 の1バイトで表現している。もちろん「x1 + x2 + x3 + x4」の値は軽く1バイトの範囲を超えるのでx1 の値を基準値として、そこからの差分の平均値を取るようにしている。

 計算式としてはこんな感じになる。
x1 + ((x2 - x1) + (x3 - x1) + (x4 - x1)) / 4

 これだと「(x2 - x1) + (x3 - x1) + (x4 - x1)」部分が例えば 128(&H80)になると、1/4の値は32(&H20)ではなく、-32(&HE0)になってしまう。ここはプログラム上の仕様なのでどうしようもない。

 というわけで、微調整だ。x1の値は、通常一番小さい値になる事が多いので、この座標 + 10H(マスの長さの半分)を基準点にしてみる。計算式としてはこんな感じになる。
x1 + ((x2 - (x1 + 10H)) + (x3 - (x1 + 10H)) + (x4 - (x1 + 10H))) / 4

 さて実行...。しばらく動かしたが、おおむね順調のようだ。

 ここまで出来た辺りで、HashiさんのHPでP6オフの案内があった。ちょうど最低限動くところまで出来た(遅いけど)ので、「妙なコネタを作っている」と書き込んだ。

2008/04/12:国会図書館
 このプログラムで当初やりたかった事がもう一つ残っている。キー入力だ。

 今までならキー入力部分はBASICで作っていたころだが、これ以上速度が遅くなるのは避けたい。思いきって、キー入力部分もマシン語化しよう。

 とはいえど、実はP6用のマシン語の本を持っていない事もあって、マシン語でどうすればキー入力が出来るかがわからない。こんな時は...国会図書館だ。以前にもここで P6のワーク領域やI/Oポートの資料を複写した事があるので、マシン語ルーチンも探せばあるだろう。

 というわけで、国会図書館に到着。入館時のカードがICカードに変わっている等電子化が進んでいたが、時間の流れが緩やかな空間は相変わらずだ。

 いくつか本を借りて、マシン語ルーチンの部分を探す。偶然なのか必然なのか、前回資料を複写した「PC-6001mkII 解析マニュアル」が一番情報が豊富だった。色んなマシン語ルーチンがあるので、まとめて複写 と思いきや、ページ数が多すぎて一度に複写できない。という事で、使いそうなものを中心に力技でノートに書き込むことにする。

 結構疲れたが、これで処理が書けそうだ。SOUND文相当のマシン語ルーチンもあったので、これで音を出すのも良いかもな、と思った。

2008/04/13:キー入力
 昨日書き込んだ資料を元に、キー入力の処理を追加する。

 キー入力ルーチンは、INKEY$相当のルーチン &H0FBC〜 を使ってみる。

 このルーチンの戻り値と反応させたいキー「QWEASDZXC」のキーコードを比較し、対応する位置のマスを押し込む処理を入れる。合わせて、BASIC側からマシン語を実行したら全てマシン語プログラム内で処理する(= BASICに戻らない)よう変更する

 処理の追加が出来たので、キー入力を試してみる。思いのほか、うまく行って満足だ。ただ、適当にキー入力していくと、また線のはみ出しが出てしまった。また微調整が必要だ...。

2008/04/17:ドレミ
 やりたかった事は一通り入れ終わったが、P6オフまでまだ期間もある事だしという事で、マスを押したときに音階が出るようにしよう。

 せっかくだから3音を独立させて鳴らしたいこともあって、音の出力は SOUND命令相当のルーチンを使う。そこで、SOUND文用の音階データを計算するために、Webで音階とその周波数の関連を探る。

 ...なんと、流派(?)によって音階と周波数との関連が微妙に異なるらしい。どれが良いのかがわからないが、きれいな音階になるとどこかで書いてあった純正律の周波数を参考に音階データを作っていく。

 一通り作成し、実行してみる。やっぱり、音が有ると無いとでは全然違う。3音独立のフェードアウトもうまくいって良かった。

 音階出力の処理を追加したので、若干ながらまた遅くなった。最後にまた処理を切り詰めて少しでも高速化に努めようと思う。

2008/04/19〜27:ちょっとだけ高速化
 SOUND音の出力はこれまで BASIC ROM内のルーチンを使用していたが、少しでも処理を切り詰めるために最低限必要な部分を抜き出して直接記述する。

変更前変更後
;SOUND 8, 0
LD A, 08H
LD E, 00H
CALL 1BC5H
;SOUND 8, 0
LD A, 08H
OUT (0A0H), A
XOR A
OUT (0A1H), A

 これで55ステートの削減だ。他の音出力部分も同様に修正する。...これで1処理辺り308ステート削減だ。

 また、画面の部分消去処理にも手を加える。ループで使っていたBレジスタをAレジスタに置き換える事で、ループ中の 表←→裏レジスタ切り替えを省略する。
変更前変更後
; A:0D4H or 0F4H
EXX ;表→裏
LD HL, 0000H
ADD HL, SP ;HL':本来のスタックポイント退避
EXX ;裏→表
LD H, A
LD L, 96H
LD DE, 0000H
LD BC, 0FFE0H
DI ;SPをいじっている間は割り込みOFF
LD SP, HL
EXX ;表→裏
LD B, 61H ;B':カウンタ
PT01:
EXX 裏→表
PUSH DE
PUSH DE
PUSH DE
PUSH DE
PUSH DE
PUSH DE
PUSH DE
ADD HL, BC
LD SP, HL
EXX 表→裏
DJNZ PT01:
LD SP, HL
EXX 裏→表
EI
; A:0D4H or 0F4H
EXX ;表→裏
LD HL, 0000H
ADD HL, SP ;HL':本来のスタックポイント退避
EXX ;裏→表
LD H, A
LD L, 96H
LD DE, 0000H
LD BC, 0FFE0H
DI ;SPをいじっている間は割り込みOFF
LD SP, HL

LD A, 61H ;A:カウンタ
PT01:

PUSH DE
PUSH DE
PUSH DE
PUSH DE
PUSH DE
PUSH DE
PUSH DE
ADD HL, BC
LD SP, HL
DEC A
JP NZ, PT01:

LD SP, HL
EXX 裏→表
EI

 これで674ステートの削減。他にもこまごまと削減していったが、結局目に見える程は速くならなかった。


その1 Making「ワイアノ」 その3