
AIを使ってMSXプログラム作成に挑戦③『全部マシン語にして』と頼んでみた
毎度、rorosukeです。
今回は「AIを使ってMSXプログラム作成に挑戦」の第3回目です。
1回目:AIのMSXプログラミング能力の検証記事
2回目:インベーダー風ゲームをSCREEN 3で作った記事
上記記事で一番の収穫は、AIを使用してマシン語プログラムが生成できたことです。特に2回目では、それなりに遊べるゲームを作り、時間のかかる一部の処理をマシン語化しています。この時点で、
部分的ではあるけれども、マシン語化までして動作したので大満足!
これでいったん終了乙!
と思っていました。しかし直後、また新たな興味がふつふつと沸いてきました。それは……!
オールマシン語化もいけんじゃね?
2回目で作ったプログラムは、BASICとマシン語の両方を使用しています。BASICで全体ループを管理し、重い処理だけをマシン語で記述して、それを呼び出す形にしています。
これでもゲームとしては十分な速さを実現できています。しかし、気になることも。それは、同じプログラムをturbo Rモードで実行して比較すると、実行速度が明らかに遅いことです。
てことは、まだまだBASICによるオーバーヘッドが大きいのかもしれません。つまり、オールマシン語化したら、もっと速く動く気がします
ちなみに、マシン語化した部分と、BASICで処理している部分をまとめるとこんな感じです。
マシン語担当部分
描画
操作・当たり判定
敵やUFOの動作
得点・ゲーム状態の管理
BASIC担当部分
起動処理(CLEAR、画面設定、DATA文からマシン語を読み込むローダー)
タイトル画面の表示と、スペースキー・トリガーの待ち
ゲーム中のメインループ(1フレームごとにマシン語を呼ぶ)と、速度調整(TIMEの待ち)
効果音(発射、爆発、ウェーブクリア、進軍音、UFOのサイレン、UFOを撃った音)
ゲームオーバー画面と、ハイスコアの管理
確かに、ゲームの心臓部はマシン語です。しかし、毎フレームでBASICに戻って、効果音を鳴らし、タイマーを待つ、という往復にかかる処理時間はそれなりにかかりそうです。
たまらずAIに依頼しました
というわけで、オールマシン語化できるのか、挑戦です。プロンプトは、
👦
オールマシン語化してくだちゃい
それだけです。前回、一部をマシン語化したのに5分ぐらいかかりました。「全部」なので、今回はもっとかかるのではないかと想像してましたが、やはり5分ぐらいでできあがりました。
できたコードはBASICプログラムです。しかし、BASICにはゲーム部分が記述されていません。BASIC文では、DATA文からマシン語を読み取って、メモリに展開し、最後に処理を丸ごと渡すだけになっています。
ゲーム本体はオールマシン語で間違いありません。
10 REM === SCREEN 3 INVADERS FULL MACHINE CODE (BASIC = loader only) ===
20 CLEAR 300,&HCFFF
30 DEFINT A-Z
40 SCREEN 0:WIDTH 40:KEY OFF:CLS:PRINT "LOADING..."
50 GOSUB 2000
60 DEFUSR=&HD000:X=USR(0)
70 SCREEN 0:KEY ON:END
2000 REM ---- LOAD MACHINE CODE (D000H) ----
2010 RESTORE 6000:A=&HD000:LN=0
2020 READ N:IF N=0 THEN LOCATE 0,3:PRINT "LOAD OK ":RETURN
2030 S=0:FOR J=1 TO N:READ D:POKE A,D:A=A+1:S=S+D:NEXT J
2035 LOCATE 0,3:PRINT "READING DATA LINE";PEEK(&HF6A3)+256*PEEK(&HF6A4);" "
2040 READ C:LN=LN+1:IF C<>S THEN PRINT "DATA ERROR LINE";5990+LN*10:END
2050 GOTO 2020
【★ここまでがBASICプログラムによるローダー】
【★以下からマシン語プログラム】
6000 DATA 16,195,59,218,195,83,208,195,9,208,62,30,50,0,230,62,3,1807
6010 DATA 16,50,1,230,175,50,2,230,50,3,230,50,4,230,50,14,230,1599
6020 DATA 16,50,15,230,50,16,230,50,80,230,50,154,230,50,155,230,50,1870
:
(略)
:
8300 DATA 16,2,7,7,1,7,4,7,7,1,7,1,7,5,5,7,1,76
8310 DATA 16,1,7,4,7,1,7,7,4,7,5,7,7,1,1,1,1,68
8320 DATA 10,7,5,7,5,7,7,5,7,1,7,58
8330 DATA 0注:上記は一部を省略しています。完全版は記事後半にファイル公開しています。
動くのか動かないのか、さあどっち!?
MSXPenで実際に走らせてみました。その結果…。
オープニング画面は表示されましたが、キー入力を受け付けず、ゲームがプレイできませんでした。
どして?
少し専門的になりますが、調査した結果、キー入力のためのBIOSの呼び出しで失敗していたことがわかりました。タイトルの「スペースキーかトリガーを押すまで待つ」処理は、次の流れで行われています。
BIOSの GTTRIG で、スペースキーが押されているかを読む
結果を B レジスタに取っておく
もう一度 GTTRIG で、ジョイスティックのトリガーを読む
二つの結果を合わせて、どちらかが押されていれば「押された」とする
BIOSのGTTRIGを2回呼び出していますが、2回目の呼び出しで、Bレジスタの値が破壊されていたために「4.」の判定が機能していませんでした。
そこで、結果をレジスタではなくメモリに保存する形にしました。修正後のルーチンは、次のとおりです。
TRIGS: xor a
call GTTRIG
ld (T_TMP),a ; 次のGTTRIG呼び出しに備え、最初の結果をメモリに保存
ld a,1
call GTTRIG
ld hl,T_TMP
or (hl)
retもっとも、この修正も「AIが調べてAIが直してくれた」ので、私は「動かないんですけど」と伝えただけです。今回は、AIが生成したコードにも、BIOS呼び出しで書き換わるレジスタへの配慮が抜けていました。しかし、失敗の情報を伝えるだけで、ほぼ自力で解決してくれました。
修正して実行したところ、ローディング、タイトル表示、ゲーム開始、爆発、UFO、ゲームオーバーまで、すべて正常に動きました。



動作速度ですが、明らかにBASIC+マシン語版より高速に動きました。ほぼturbo Rモードで実行したときと同程度です。
BASIC併用版より速い:ゲームの進行をこなすたびにBASICを経由する必要がなくなったためでしょう
turbo Rモードぐらいの速度が出ている:前回のBASIC併用版ではturbo Rの方が動きが速かったのですが、オールマシン語版は同じぐらいの動きになっています
ちなみに、処理速度が上がったことでゲームの難易度も上がってます。
サーセン。
ダウンロードとプレイ方法
MSXPenへのリンクを作ったので、次にアクセスすればすぐオンライン上で実行できます。
フルマシン語版のファイルも公開します。
INVADERS_FULLMC.BAS
プレイ方法
MSXPen(オンラインのMSXエミュレータ)を開きます
INVADERS_FULLMC.BAS を読み込んで、RUN します
ロード中は、読み込んでいるDATA行の番号が表示されます
タイトル画面でスペースキー(またはトリガー)を押すと、ゲームが始まります
キー操作
移動:カーソルキー、またはジョイスティックの左右
発射:スペースキー、またはトリガーボタン
タイトル画面でスペースキーを押すとスタートします
確認環境について
動作は、MSXPenで確認しています。実機やopenMSXでは確認していません。環境によって、速度や音が違う場合があります。
まとめ:過去に戻らせてクレ!
考えてもみてください。
MSXはもう40年も前の8ビットパソコンです。
そして、当時はマシン語でのゲーム開発というのは、Z80の知識、MSXの知識、BIOSの知識、アセンブラなどのツールの知識などを総動員しないと作れないものです。
そのようなお膳立てがあっても、開発には何日もかかります。かなり腕のある人でも、このプログラムを作るのに1か月ぐらいはかかるでしょう。当時の私にとっては、とても気軽に挑戦できるものではありませんでした。半年から1年かけても、完成させられたかどうか。
それが今は、AIとやり取りしながら、2、3日で動くところまで持っていけるのです。
なんちゅうドリーム!
昔を思い出すと泣きそうになりますね。タイムマシンがあったら、過去に戻って、カリスマ開発者として名声を欲しいままにしてみたいです(笑)
以上!
追記:続きの記事を書きました
高速起動を実現しています。
#時産時利 #AI活用 #時短術 #MSX #マシン語 #Z80 #Claude #生成AI #AIプログラミング #レトロゲーム #レトロパソコン