2026.7.26
前へ
次へ
ホームページトップへ戻る


[新連載開始]W65C02マイコンボードの製作

〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
私としてはW65C02をさわるのは全く初めてです。何から何まで未経験です。さてどうなりますでしょうか。
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜

[第24回]



●BRA(2)前方への相対ジャンプ

前回の説明を一部訂正しました。
昨日UPした時点ではBBRとBBSの説明は第1オペランドがジャンプ先までの差分で第2オペランドが対象とするゼロページアドレスとしていました。
実は本日になってそこのところが気になったので急いでテストプログラムを作ってテストして確認してみたところそれが逆であることがわかりました。
正しくは第1オペランドがゼロページアドレスで第2オペランドが移動差分値でした。
そのテストについてはいずれ回が進んだところで説明することになると思いますが前回の説明が間違いであることがわかりましたのでとりあえずそこのところは急遽訂正いたしました。
今は正しい記述になっています。

相対ジャンプ命令はオペランドとしてジャンプ先までの移動距離(バイト数)を算出しなければなりません。
そもそもその移動距離はどこからどこまでなのか。
前回書きましたようにもしもW65C02のBRA命令がZ80のJR命令と同じ考え方で組まれた命令ならばその移動距離は現在のPC(プログラムカウンタ)の値を起点とするはずです。
しかしそれは現時点ではただの推理推測にすぎません。
マシン語でプログラムを書く場合にはその値を求めることは必須になります。
実際のところそれはどういう値になるのかそれを確認しなければなりません。
それにはやっぱり実際にプログラムを書いてそれを実行して確認するのが一番確実です。
それを確認するための簡単なプログラムを作りました。
こちらがソースプログラムです。
       ;w65c02test5 26.7.23
        ;
        org $8000
;
        lda #$00
        bra $02
        inc
        inc
        inc
        inc
        inc
        inc
        sta $12
        stp
;end

アキュムレータに0を入れた後BRA命令を実行します。
そのオペランドにはテストのための値として02を置きました。
その後には連続したINC命令を置いています。
BRA命令の実行によって何番目かのINC命令にジャンプするはずです。
最後にアキュムレータの値を0012番地に入れてストップします。
これはアセンブラソースプログラムですからまずはW65C02アセンブラが正しいマシン語コードに翻訳することが求められます。
アセンブラを自作するということはそこから考えていくということです。
なかなかに面倒な作業をやっているのです。
下は自作したW65C02アセンブラで上記のソースプログラムをアセンブルした結果生成されたアセンブルリストです。
0000           ;w65c02test5 26.7.23
0000            ;
8000            org $8000
8000        ;
8000 A900       lda #$00
8002 8002       bra $02
8004 1A         inc
8005 1A         inc
8006 1A         inc
8007 1A         inc
8008 1A         inc
8009 1A         inc
800A 8512       sta $12
800C DB         stp
800D        ;end

下はW65C02アセンブラを実行したときの画面です。

アセンブルリストとともにバイナリファイルも生成されています。
表示されているマシン語コードを見る限り正しいマシン語コードが生成されているようです。
作成されたバイナリファイルは65c02test5.binです。
ところで今回のBRA命令のためにW65C02アセンブラの追加編集作業をする過程で気がついたのですが。
W65C02のアセンブラルールでは$02はゼロページアドレスを示します([第21回]参照)。
BRA命令のオペランドはアドレスではなくてただの値ですからここはその上のLDAのオペランドと同様に#$02と表記すべきです。
でもせっかくこのように作った自作アセンブラですしBRAのオペランドには「値」しか入りませんからここは「表記が間違っています」なんて固いことは言わないでこのまま通すことにしました。
もちろん本来の正しい表記である#$02でもOKです。
下はそのように書いたソースプログラムをW65C02アセンブラでアセンブルしたときの画像です。
どちらの表記でも同じバイナリコードが生成されます。


テストプログラム65c02test5.binをロードしました。

プログラムを実行すると計算後のアキュムレータの値が0012に書き込まれます。
実行前に0012の値を/CMコマンドで確認しました。
今の値はDEです。
/RUNコマンドを実行後にもう一度/CMコマンドを実行して0012の値を確認しました。
値は04になりました。
ということは。
アキュムレータに00を入れて実行した結果04になったということですからINC命令が4回実行されたことになります。
もう一度65c02test5のリストファイルを再掲します。
0000           ;w65c02test5 26.7.23
0000            ;
8000            org $8000
8000        ;
8000 A900       lda #$00
8002 8002       bra $02
8004 1A         inc
8005 1A         inc
8006 1A         inc
8007 1A         inc
8008 1A         inc
8009 1A         inc
800A 8512       sta $12
800C DB         stp
800D        ;end

INCが4回実行されたということはBRA 02の実行によってアドレス8006にジャンプしたことになります。
前回の推測ではBRA 02はそのマシン語コードを読み込んだ直後のPCの値に2を加算したアドレスにジャンプするはずです。
推測ではBRA 02を読み込んだ直後にPCは8004になっているはずです。
そこに+2を加えると。
PCの値は8006になります。
テストプログラムの実行結果と一致しました。
前回推測した通り相対ジャンプ命令のオペランドにはその次のアドレスを起点としてジャンプ先アドレスまでの差分をいれればよいということが確かめられました。

W65C02マイコンボードの製作[第24回]
2026.7.26 upload

前へ
次へ
ホームページトップへ戻る