以前、ファミコンのゲームを開発した際、コマンドライン上でレジスタ値やメモリダンプの簡易チェックができるCLIが欲しかったのですが、そもそも「コマンドラインでゲームをステップ実行できるNESエミュレータ」というものが(軽く探してみた限りですが)見つかりませんでした。GUIでメモリダンプやステップ実行できるものなら幾らかありましたが。
という訳でコマンドライン上で実行できるVGS8のデバッガ(vgsrun)を作成。
実行すると上図のように現在のプログラムカウンタ上の命令を逆アセンブルしながら、レジスタダンプ(a, x, y, s, p)を右側に出力します。(赤くなっている部分は前ステップからレジスタ値が変化したもの)
そのまま実行すると、1フレーム分の命令実行終了で自動的に終了します。
※コマンド引数で実行するフレーム数を任意に指定可能
先日作ったVGS8版Hello, Worldを1フレーム実行した結果
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$ bin/vgsrun examples/hello/hello.rom | |
$8000: LDA #$00 (a=$00, x=$00, y=$00, s=$00, p=$02) | |
$8002: STA $5404 (a=$00, x=$00, y=$00, s=$00, p=$02) | |
$8005: LDX #$00 (a=$00, x=$00, y=$00, s=$00, p=$02) | |
$8007: LDA $8018, X (a=$48, x=$00, y=$00, s=$00, p=$00) | |
$800A: STA $63C7, X (a=$48, x=$00, y=$00, s=$00, p=$00) | |
$800D: INX (a=$48, x=$01, y=$00, s=$00, p=$00) | |
$800E: CPX #$12 (a=$48, x=$01, y=$00, s=$00, p=$80) | |
$8010: BNE $F5 (a=$48, x=$01, y=$00, s=$00, p=$80) | |
$8007: LDA $8018, X (a=$65, x=$01, y=$00, s=$00, p=$00) | |
$800A: STA $63C7, X (a=$65, x=$01, y=$00, s=$00, p=$00) | |
$800D: INX (a=$65, x=$02, y=$00, s=$00, p=$00) | |
$800E: CPX #$12 (a=$65, x=$02, y=$00, s=$00, p=$80) | |
$8010: BNE $F5 (a=$65, x=$02, y=$00, s=$00, p=$80) | |
$8007: LDA $8018, X (a=$6C, x=$02, y=$00, s=$00, p=$00) | |
$800A: STA $63C7, X (a=$6C, x=$02, y=$00, s=$00, p=$00) | |
$800D: INX (a=$6C, x=$03, y=$00, s=$00, p=$00) | |
$800E: CPX #$12 (a=$6C, x=$03, y=$00, s=$00, p=$80) | |
$8010: BNE $F5 (a=$6C, x=$03, y=$00, s=$00, p=$80) | |
$8007: LDA $8018, X (a=$6C, x=$03, y=$00, s=$00, p=$00) | |
$800A: STA $63C7, X (a=$6C, x=$03, y=$00, s=$00, p=$00) | |
$800D: INX (a=$6C, x=$04, y=$00, s=$00, p=$00) | |
$800E: CPX #$12 (a=$6C, x=$04, y=$00, s=$00, p=$80) | |
$8010: BNE $F5 (a=$6C, x=$04, y=$00, s=$00, p=$80) | |
$8007: LDA $8018, X (a=$6F, x=$04, y=$00, s=$00, p=$00) | |
$800A: STA $63C7, X (a=$6F, x=$04, y=$00, s=$00, p=$00) | |
$800D: INX (a=$6F, x=$05, y=$00, s=$00, p=$00) | |
$800E: CPX #$12 (a=$6F, x=$05, y=$00, s=$00, p=$80) | |
$8010: BNE $F5 (a=$6F, x=$05, y=$00, s=$00, p=$80) | |
$8007: LDA $8018, X (a=$2C, x=$05, y=$00, s=$00, p=$00) | |
$800A: STA $63C7, X (a=$2C, x=$05, y=$00, s=$00, p=$00) | |
$800D: INX (a=$2C, x=$06, y=$00, s=$00, p=$00) | |
$800E: CPX #$12 (a=$2C, x=$06, y=$00, s=$00, p=$80) | |
$8010: BNE $F5 (a=$2C, x=$06, y=$00, s=$00, p=$80) | |
$8007: LDA $8018, X (a=$20, x=$06, y=$00, s=$00, p=$00) | |
$800A: STA $63C7, X (a=$20, x=$06, y=$00, s=$00, p=$00) | |
$800D: INX (a=$20, x=$07, y=$00, s=$00, p=$00) | |
$800E: CPX #$12 (a=$20, x=$07, y=$00, s=$00, p=$80) | |
$8010: BNE $F5 (a=$20, x=$07, y=$00, s=$00, p=$80) | |
$8007: LDA $8018, X (a=$56, x=$07, y=$00, s=$00, p=$00) | |
$800A: STA $63C7, X (a=$56, x=$07, y=$00, s=$00, p=$00) | |
$800D: INX (a=$56, x=$08, y=$00, s=$00, p=$00) | |
$800E: CPX #$12 (a=$56, x=$08, y=$00, s=$00, p=$80) | |
$8010: BNE $F5 (a=$56, x=$08, y=$00, s=$00, p=$80) | |
$8007: LDA $8018, X (a=$47, x=$08, y=$00, s=$00, p=$00) | |
$800A: STA $63C7, X (a=$47, x=$08, y=$00, s=$00, p=$00) | |
$800D: INX (a=$47, x=$09, y=$00, s=$00, p=$00) | |
$800E: CPX #$12 (a=$47, x=$09, y=$00, s=$00, p=$80) | |
$8010: BNE $F5 (a=$47, x=$09, y=$00, s=$00, p=$80) | |
$8007: LDA $8018, X (a=$53, x=$09, y=$00, s=$00, p=$00) | |
$800A: STA $63C7, X (a=$53, x=$09, y=$00, s=$00, p=$00) | |
$800D: INX (a=$53, x=$0A, y=$00, s=$00, p=$00) | |
$800E: CPX #$12 (a=$53, x=$0A, y=$00, s=$00, p=$80) | |
$8010: BNE $F5 (a=$53, x=$0A, y=$00, s=$00, p=$80) | |
$8007: LDA $8018, X (a=$38, x=$0A, y=$00, s=$00, p=$00) | |
$800A: STA $63C7, X (a=$38, x=$0A, y=$00, s=$00, p=$00) | |
$800D: INX (a=$38, x=$0B, y=$00, s=$00, p=$00) | |
$800E: CPX #$12 (a=$38, x=$0B, y=$00, s=$00, p=$80) | |
$8010: BNE $F5 (a=$38, x=$0B, y=$00, s=$00, p=$80) | |
$8007: LDA $8018, X (a=$20, x=$0B, y=$00, s=$00, p=$00) | |
$800A: STA $63C7, X (a=$20, x=$0B, y=$00, s=$00, p=$00) | |
$800D: INX (a=$20, x=$0C, y=$00, s=$00, p=$00) | |
$800E: CPX #$12 (a=$20, x=$0C, y=$00, s=$00, p=$80) | |
$8010: BNE $F5 (a=$20, x=$0C, y=$00, s=$00, p=$80) | |
$8007: LDA $8018, X (a=$57, x=$0C, y=$00, s=$00, p=$00) | |
$800A: STA $63C7, X (a=$57, x=$0C, y=$00, s=$00, p=$00) | |
$800D: INX (a=$57, x=$0D, y=$00, s=$00, p=$00) | |
$800E: CPX #$12 (a=$57, x=$0D, y=$00, s=$00, p=$80) | |
$8010: BNE $F5 (a=$57, x=$0D, y=$00, s=$00, p=$80) | |
$8007: LDA $8018, X (a=$6F, x=$0D, y=$00, s=$00, p=$00) | |
$800A: STA $63C7, X (a=$6F, x=$0D, y=$00, s=$00, p=$00) | |
$800D: INX (a=$6F, x=$0E, y=$00, s=$00, p=$00) | |
$800E: CPX #$12 (a=$6F, x=$0E, y=$00, s=$00, p=$80) | |
$8010: BNE $F5 (a=$6F, x=$0E, y=$00, s=$00, p=$80) | |
$8007: LDA $8018, X (a=$72, x=$0E, y=$00, s=$00, p=$00) | |
$800A: STA $63C7, X (a=$72, x=$0E, y=$00, s=$00, p=$00) | |
$800D: INX (a=$72, x=$0F, y=$00, s=$00, p=$00) | |
$800E: CPX #$12 (a=$72, x=$0F, y=$00, s=$00, p=$80) | |
$8010: BNE $F5 (a=$72, x=$0F, y=$00, s=$00, p=$80) | |
$8007: LDA $8018, X (a=$6C, x=$0F, y=$00, s=$00, p=$00) | |
$800A: STA $63C7, X (a=$6C, x=$0F, y=$00, s=$00, p=$00) | |
$800D: INX (a=$6C, x=$10, y=$00, s=$00, p=$00) | |
$800E: CPX #$12 (a=$6C, x=$10, y=$00, s=$00, p=$80) | |
$8010: BNE $F5 (a=$6C, x=$10, y=$00, s=$00, p=$80) | |
$8007: LDA $8018, X (a=$64, x=$10, y=$00, s=$00, p=$00) | |
$800A: STA $63C7, X (a=$64, x=$10, y=$00, s=$00, p=$00) | |
$800D: INX (a=$64, x=$11, y=$00, s=$00, p=$00) | |
$800E: CPX #$12 (a=$64, x=$11, y=$00, s=$00, p=$80) | |
$8010: BNE $F5 (a=$64, x=$11, y=$00, s=$00, p=$80) | |
$8007: LDA $8018, X (a=$21, x=$11, y=$00, s=$00, p=$00) | |
$800A: STA $63C7, X (a=$21, x=$11, y=$00, s=$00, p=$00) | |
$800D: INX (a=$21, x=$12, y=$00, s=$00, p=$00) | |
$800E: CPX #$12 (a=$21, x=$12, y=$00, s=$00, p=$03) | |
$8010: BNE $F5 (a=$21, x=$12, y=$00, s=$00, p=$03) | |
$8012: LDA $5BFF (a=$00, x=$12, y=$00, s=$00, p=$03) | |
FRAME #1 END (2ms, 282Hz) | |
$ |
これで、ゲーム開発もVGS8本体開発も大分捗りそうです。
将来的にはもっと拡張して、
・ブレイクポイントの途中書き換え
・ステップ実行
あたりも欲しいかも。
0 件のコメント:
コメントを投稿
注: コメントを投稿できるのは、このブログのメンバーだけです。