メインコンテンツへスキップ
見出し画像

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の呼び出しで失敗していたことがわかりました。タイトルの「スペースキーかトリガーを押すまで待つ」処理は、次の流れで行われています。

    1. BIOSの GTTRIG で、スペースキーが押されているかを読む

    2. 結果を B レジスタに取っておく

    3. もう一度 GTTRIG で、ジョイスティックのトリガーを読む

    4. 二つの結果を合わせて、どちらかが押されていれば「押された」とする

    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モードで実行したときと同程度です。

    1. BASIC併用版より速い:ゲームの進行をこなすたびにBASICを経由する必要がなくなったためでしょう

    2. turbo Rモードぐらいの速度が出ている:前回のBASIC併用版ではturbo Rの方が動きが速かったのですが、オールマシン語版は同じぐらいの動きになっています

    ちなみに、処理速度が上がったことでゲームの難易度も上がってます。
    サーセン。



    ダウンロードとプレイ方法

    MSXPenへのリンクを作ったので、次にアクセスすればすぐオンライン上で実行できます。

    フルマシン語版のファイルも公開します。

    INVADERS_FULLMC.BAS

    プレイ方法

    1. MSXPen(オンラインのMSXエミュレータ)を開きます

    2. INVADERS_FULLMC.BAS を読み込んで、RUN します

    3. ロード中は、読み込んでいるDATA行の番号が表示されます

    4. タイトル画面でスペースキー(またはトリガー)を押すと、ゲームが始まります

    キー操作

    • 移動:カーソルキー、またはジョイスティックの左右

    • 発射:スペースキー、またはトリガーボタン

    • タイトル画面でスペースキーを押すとスタートします

    確認環境について

    動作は、MSXPenで確認しています。実機やopenMSXでは確認していません。環境によって、速度や音が違う場合があります。



    まとめ:過去に戻らせてクレ!

    考えてもみてください。
    MSXはもう40年も前の8ビットパソコンです。

    そして、当時はマシン語でのゲーム開発というのは、Z80の知識、MSXの知識、BIOSの知識、アセンブラなどのツールの知識などを総動員しないと作れないものです。

    そのようなお膳立てがあっても、開発には何日もかかります。かなり腕のある人でも、このプログラムを作るのに1か月ぐらいはかかるでしょう。当時の私にとっては、とても気軽に挑戦できるものではありませんでした。半年から1年かけても、完成させられたかどうか。

    それが今は、AIとやり取りしながら、2、3日で動くところまで持っていけるのです。

    なんちゅうドリーム!


    昔を思い出すと泣きそうになりますね。タイムマシンがあったら、過去に戻って、カリスマ開発者として名声を欲しいままにしてみたいです(笑)

    以上!



    追記:続きの記事を書きました

    高速起動を実現しています。

    #時産時利 #AI活用 #時短術 #MSX #マシン語 #Z80 #Claude #生成AI #AIプログラミング #レトロゲーム #レトロパソコン

     
     
    AIで時間を生み出す実験をしています。 元PC系出版社編集者。 Claude・ChatGPT・Geminiを並行使用しながら、 実践した話だけを書いています。

    あなたへのおすすめ