自伝(その3)〜BASIC からマシン語へ〜
ゲームプログラムの構造
さて,中学生の時に,PC-6001mkII を買ってもらい,雑誌掲載の BASIC プログラムリストを打ち込んでは遊ぶことを繰り返していくうちに,なんとなくゲームの作り方が見えてくるようになりました。
- ゲームのプログラムは全体で大きなループを繰り返す
- 動くモノの状態(位置など)は変数に入れておく
- キー入力から動くモノ(自分)の状態を更新する
- 動くモノ(敵)は自分の動きから計算または乱数で状態を更新する
- 動くモノの位置は LOCATE で指定して PRINT で表示する
ゲームにするにはその他いろいろな判定が必要なのですが,概ねこれらを繰り返すとゲームっぽい画面が表示できます。(テキスト文字を使ったチープなゲームですが)
BASIC でグラフィック表示をすると重い!
ただ,市販ゲームのようにグラフィック表示を使うと,途端に処理が重くなり,まともに遊べないことに気が付きます。
他のマイコン雑誌を見て調べてみると,マシン語を使うとエライ高速に実行できるということがわかりました。
当時の市販ゲームソフトのパッケージに「オールマシン語」と書かれていて,よく意味がわからなかったのですが,そういうことか〜!と納得します。
マシン語って何?
マシン語を使ったプログラムリストを見てみると,16進数と言われる,0〜9 と A〜F の組み合わせの数値がズラ〜っと並んでいます。
BASIC プログラムは命令が INPUT とか PRINT とか GOTO など大体英単語で,中学生の自分でも何となく意味がわかりますが,マシン語の 3E 01 32 00 C0 とか暗号のようにしか見えません。
「マシン語を使ってプログラムを組む人はこの暗号を理解するのか〜?敷居高いな〜」と思いました。
そこで何はともあれ,本屋さんに行き,マシン語の入門書を買いました。
なるほど… Z80 という CPUのアセンブリ言語というものからアセンブル(変換)するとこの暗号のようなマシン語になるのか〜。
PC-6001mkII のマニュアル巻末にある変換表はこれだったのか〜。と妙に納得します。
ハンドアセンブルがすごく面倒くさい
Z80 のアセンブリ言語は,大きく以下の命令体型に分類することができます。
- 転送命令 (LD,PUSH とか)
- 入出力命令 (IN,OUT とか)
- 算術演算命令(ADD,SUB,CP とか)
- 論理演算命令(AND,OR,XOR とか)
- ローテイト・シフト命令(SRL,RR とか)
- ビット処理命令(BIT,SET,RES とか)
- ジャンプ・コール・リターン命令(JP,CALL,RET とか)
これらの一つ一つの命令が 16 進数の何かに対応していて,その 16 進数の羅列を CPU が処理していることがわかりました。
今でこそ,このような変換処理は専用ツールでコンピュータに処理させるのが当たり前なんですが,当時の貧弱なメモリと外部記憶装置がカセットテープだった環境では,そのような環境は夢のようなもので(全くできないわけでもありませんでしたが…)自分の手で変換表を元に変換しなくてはならないのでした。
これをハンドアセンブルと言います。
ROM BASIC 上では,BASIC プログラムしか入力できないので,ノートに Z80 のアセンブリ言語(それぞれの命令はニーモニックと言います)を書き,変換表を元にハンドアセンブルを行います。
プログラム言語には必ず分岐(ジャンプ)というものがありますが,この分岐命令も分岐先を 16 進数で指定しなければなりません。
後方ジャンプ,すなわち現在の命令よりもアドレスが少ない方にジャンプする場合は,すでにアドレスが決まっているのですが,前方ジャンプ,現在の命令よりも先にあるアドレスにジャンプする場合は,そのジャンプ先までハンドアセンブルしないとアドレスが決まりません。(ある程度余裕を持ってかなり前方の決まったアドレスにするという方法もありますが,メモリがもったいない)
取り敢えずジャンプ先の 16 進数は空欄にしておいてジャンプ先のアドレスが決まってから埋めるというとても面倒な作業でした。
そしてマシン語をなんとか理解する
ノートに Z80 のニーモニックを書いて,ハンドアセンブルでマシン語に変換し,16 進数をまたノートに書き込んでいく。
こんなことを繰り返すと,自然とよく使うニーモニックは変換後の 16進数を頭で覚えてしまいます。
Z80 を経験した人なら,00,FF,3E,21,AF,C3,CD,C9 といったマシン語は覚えてしまっているのではないでしょうか?