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


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

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

[第42回]



●ADC,SBC(2)ADCテストプログラム

ADCとSBCは演算が加算か減算かという違いがあるだけでその他は同じです。
実はCフラグの扱いが異なることがわかりました。
それについては後の回で説明することにしてまずはADCについて検証することにしました。
今回はフラグについても確認をしたいと思います。
W65C02アセンブラの動作確認という点では正しいコードさえ出力されれば検証の目的のひとつは達成されたことになります。
しかしせっかくプログラムを作るのですから演算結果やフラグについても確認することでW65C02の命令の理解が更に深まることになります。
W65C02アセンブラによって作成されたマシン語プログラムを実行してそれが理屈通りの結果になればその命令の機能を私自身が正しく理解した結果であると言うことができますし同時にW65C02アセンブラの正しさも確認できたことになります。
しかしながら。
LDA、STAのときもそうでしたがこのテストプログラムを作るというのがなかなかに面倒な作業なのです。
なにしろW65C02はアドレッシングモードが実に多様でややこしいのです。
その全てを網羅したプログラムにしなければテストになりません。
結果としてなんじゃこりゃあというややこしいプログラムになってしまいます。
LDA、STAのときよりは分かり易いプログラムを書くように努めましたが果たしてどうでしょうか。
演算結果とともにフラグの確認もしたいと思いましたのでスタックを利用するように考えました。
W65C02のスタックエリアは0100〜01FFに割り当てられています。
リセット後はSP(スタックポインタ)はFDに初期セットされます(ここもそうではないらしいということが後になってわかってきました)。
スタックに値をPUSHするとその値は01FDから前方に順に格納されていきますからプログラムの実行後に0100〜01FFを確認すれば結果の確認ができるはずです。
下はそういう考えで作ったADCテストプログラムです。
;w65c02test18 26.8.8
;
;ADC
;
        org $8000
;
;set data
        ldx #$10
        ldy #$20
        lda #$12
        sta $1000;1000<12,,,a
        lda #$34
        sta $1000,x;1010<34,,,a,x
        lda #$56
        sta $1000,y;1020<56,,,a,y
        lda #$78
        sta $10;10<78,,,zp
        lda #$10
        sta $10,x;20<10,,,(zp,x)
        sta $11,x;21<10,,,1010
        sta $23;23<10,,,(zp)
        lda #$20
        sta $22;22<20,,,1020
        ;$00,x,,,10<78 zp,x
        ;zp=10,(zp)=1010,(zp),y=1030
        lda #$9a
        sta $1030
;
;start
        tsx;stack pointer to x
        stx $30
;
        lda #$9a
        ldx #$10
        ldy #$20
;
        php;flug=34 00110100
        pha;9a
        adc $1000;9a+12=ac n=1
        php;b4 10110100
        pha;ac
        adc $1000,x;ac+34=e0 n=1
        php;b4
        pha;e0
        adc $1000,y;e0+56=36 c=1
        php;35 00110101
        pha;36
        adc #$bc;36+bc+1=f3 n=1
        php;b4 10110100
        pha;f3
        adc $10;f3+78=6b c=1
        php;35 00110101
        pha;6b
        adc ($10,x);20,21,,,1010<34,,,(zp,x) 6b+34+1=a0 n=1 v=1
        php;f4 11110100
        pha;a0
        adc ($22);22,23,,,1020<56,,,(zp) a0+56=f6 n=1
        php;b4 10110100
        pha;f6
        adc $00,x;,,,10<78,,,zp,x f6+78=6e c=1
        php;35 00110101
        pha;6e
        adc ($20),y;($20)=1010,y=20,,,1030<9a 6e+9a+1=09 c=1
        php;35 00110101
        pha;09
        tsx;stack pointer to x
        stx $31;e9
        stp
;end
W65C02アセンブラでアセンブルしました。

下はアセンブルした結果作成されたアセンブルリストです。
0000        ;w65c02test18 26.8.8
0000        ;
0000        ;ADC
0000        ;
8000            org $8000
8000        ;
8000        ;set data
8000 A210       ldx #$10
8002 A020       ldy #$20
8004 A912       lda #$12
8006 8D0010     sta $1000;1000<12,,,a
8009 A934       lda #$34
800B 9D0010     sta $1000,x;1010<34,,,a,x
800E A956       lda #$56
8010 990010     sta $1000,y;1020<56,,,a,y
8013 A978       lda #$78
8015 8510       sta $10;10<78,,,zp
8017 A910       lda #$10
8019 9510       sta $10,x;20<10,,,(zp,x)
801B 9511       sta $11,x;21<10,,,1010
801D 8523       sta $23;23<10,,,(zp)
801F A920       lda #$20
8021 8522       sta $22;22<20,,,1020
8023            ;$00,x,,,10<78 zp,x
8023            ;zp=10,(zp)=1010,(zp),y=1030
8023 A99A       lda #$9a
8025 8D3010     sta $1030
8028        ;
8028        ;start
8028 BA         tsx;stack pointer to x
8029 8630       stx $30
802B        ;
802B A99A       lda #$9a
802D A210       ldx #$10
802F A020       ldy #$20
8031        ;
8031 08         php;flug=34 00110100
8032 48         pha;9a
8033 6D0010     adc $1000;9a+12=ac n=1
8036 08         php;b4 10110100
8037 48         pha;ac
8038 7D0010     adc $1000,x;ac+34=e0 n=1
803B 08         php;b4
803C 48         pha;e0
803D 790010     adc $1000,y;e0+56=36 c=1
8040 08         php;35 00110101
8041 48         pha;36
8042 69BC       adc #$bc;36+bc+1=f3 n=1
8044 08         php;b4 10110100
8045 48         pha;f3
8046 6510       adc $10;f3+78=6b c=1
8048 08         php;35 00110101
8049 48         pha;6b
804A 6110       adc ($10,x);20,21,,,1010<34,,,(zp,x) 6b+34+1=a0 n=1 v=1
804C 08         php;f4 11110100
804D 48         pha;a0
804E 7222       adc ($22);22,23,,,1020<56,,,(zp) a0+56=f6 n=1
8050 08         php;b4 10110100
8051 48         pha;f6
8052 7500       adc $00,x;,,,10<78,,,zp,x f6+78=6e c=1
8054 08         php;35 00110101
8055 48         pha;6e
8056 7120       adc ($20),y;($20)=1010,y=20,,,1030<9a 6e+9a+1=09 c=1
8058 08         php;35 00110101
8059 48         pha;09
805A BA         tsx;stack pointer to x
805B 8631       stx $31;e9
805D DB         stp
805E        ;end

これじゃあわかりませんよねえ。
set dataのところで演算に使う値(適当です)をメモリにセットしておきます。
上のほうでも書きましたがとにかくW65C02のアドレッシングモードはややこしいです。
演算する度に結果の値とフラグをスタックにPUSHします。
PHPはフラグをPUSHする命令です。
W65C02のフラグレジスタはProcessor Statusといいます。
PHAはアキュムレータをスタックにPUSHする命令です。
最後に使ったTSXはスタックポインタをXレジスタに転送する命令です(Transfar Stack Pointer to Index X)。
PHP、PHA、TSXもテストするというおまけ付きです。
65c02test18.binをロードして実行しました。

0030にはプログラム開始時のスタックポインタの値FDが、0031にはプログラム終了時の値E9が書き込まれています。
その値から見てプログラムは無事実行されたようです。

/DM 01を実行してスタックの中身を表示させました。

00E8〜00FDに演算結果のフラグと結果の値が格納されています。
この値を鉛筆舐め舐めチェックした結果全部計算通りであることを確認しました。
確認できましたからそれでよいようなものですがLDA、STAのときと同じように結果の照合もプログラムでするようにすればCPUが正常動作しているかどうかの判定にも使えます。
ということで。
チェック部分を追加しました。
それは次回にて。

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

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