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


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

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

[第44回]



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

今回はSBCのテストプログラムです。
基本的な考え方はADCのテストプログラムと同じです。
ところがそのつもりで最初に作ったプログラムを実行してみたところ演算の結果が想定した計算結果と合いません。
あまりにおかしいので詳しく調べたところSBCのCフラグは普通にイメージしているボローとは扱いが異なっていました。
どうしてそういう仕様になっているのか何かそれなりの理由があるのでしょうがよくわかりません。
SBCのCフラグはボローがあるときにクリアされ(C=0)ボローが発生しないときはセットされます(C=1)。
なんとややこしい。
頭が混乱してしまいます。
下はそこのところを考慮して正しい結果が得られるようにしたテストプログラムです。
;w65c02test19 26/8/9
;
;SBC
;
        org $8000
;
;       $30 stack on start
;       $31 stack on stop
;       $32 x on end of check(if not ff x is error adrs)
;       $33 y stack on end of check
;       $34 data
;       $35 stack data
;
;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
        sbc $1000;9a-12-1=87 n=1 c=1
        php;b5 10110101
        pha;87
        sbc $1000,x;87-34=53 v=1 c=1
        php;75 01110101
        pha;53
        sbc $1000,y;53-56=fd n=1 c=0
        php;b4 10110100
        pha;fd
        sbc #$bc;fd-bc-1=40 c=1
        php;35 00110101
        pha;40
        sbc $10;40-78=c8 n=1 c=0
        php;b4 10110100
        pha;c8
        sbc ($10,x);20,21,,,1010<34,,,(zp,x) c8-34-1=93 n=1 c=1
        php;b5 10110101
        pha;93
        sbc ($22);22,23,,,1020<56,,,(zp) 93-56=3d v=1 c=1
        php;75 01110101
        pha;3d
        sbc $00,x;,,,10<78,,,zp,x 3d-78=c5 n=1 c=0
        php;b4 10110100
        pha;c5
        sbc ($20),y;($20)=1010,y=20,,,1030<9a c5-9a-1=2a c=1
        php;35 00110101
        pha;2a
        tsx;stack pointer to x
        stx $31;e9
;
;check data set
        lda #$2a
        sta $40
        lda #$01
        sta $41
        lda #$c5
        sta $42
        lda #$80
        sta $43
        lda #$3d
        sta $44
        lda #$41
        sta $45
        lda #$93
        sta $46
        lda #$81
        sta $47
        lda #$c8
        sta $48
        lda #$80
        sta $49
        lda #$40
        sta $4a
        lda #$01
        sta $4b
        lda #$fd
        sta $4c
        lda #$80
        sta $4d
        lda #$53
        sta $4e
        lda #$41
        sta $4f
        lda #$87
        sta $50
        lda #$81
        sta $51
;
;check start
        ldx #$11
        ldy #$fb
loop:
        lda $0100,y
        and #$c3;stack
        cmp $40,x
        bne err
        dey
        dex
        lda $0100,y
        cmp $40,x;code
        bne err
        dey
        dex
        bpl loop;end if x=ff
;check end
err:
        stx $32
        sty $33
        sta $35
        lda $40,x
        sta $34
        stp
;end
SBC命令のところはよくよく考えないとCフラグのセットリセットを間違えてしまいます。
それでコメントとして命令の後ろに追記したのですが試しに実行してみるとやっぱり間違えているところがありました。
上のプログラムは試しに実行して結果を確認して補正をしながら作りました。
実に何だかなあという思いです。
ADCテストプログラムのときと同じようにプログラムの後半で計算結果をチェックしています。
特にSBCについてはこれは必須でありましょう。
フラグはN、V、Z、C(ビット7、6、1、0)以外はANDでマスクしています。
W65C02アセンブラでアセンブルしました。

下はアセンブルした結果作成されたアセンブルリストです。
0000        ;w65c02test19 26/8/9
0000        ;
0000        ;SBC
0000        ;
8000            org $8000
8000        ;
8000        ;   $30 stack on start
8000        ;   $31 stack on stop
8000        ;   $32 x on end of check(if not ff x is error adrs)
8000        ;   $33 y stack on end of check
8000        ;   $34 data
8000        ;   $35 stack data
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 ED0010     sbc $1000;9a-12-1=87 n=1 c=1
8036 08         php;b5 10110101
8037 48         pha;87
8038 FD0010     sbc $1000,x;87-34=53 v=1 c=1
803B 08         php;75 01110101
803C 48         pha;53
803D F90010     sbc $1000,y;53-56=fd n=1 c=0
8040 08         php;b4 10110100
8041 48         pha;fd
8042 E9BC       sbc #$bc;fd-bc-1=40 c=1
8044 08         php;35 00110101
8045 48         pha;40
8046 E510       sbc $10;40-78=c8 n=1 c=0
8048 08         php;b4 10110100
8049 48         pha;c8
804A E110       sbc ($10,x);20,21,,,1010<34,,,(zp,x) c8-34-1=93 n=1 c=1
804C 08         php;b5 10110101
804D 48         pha;93
804E F222       sbc ($22);22,23,,,1020<56,,,(zp) 93-56=3d v=1 c=1
8050 08         php;75 01110101
8051 48         pha;3d
8052 F500       sbc $00,x;,,,10<78,,,zp,x 3d-78=c5 n=1 c=0
8054 08         php;b4 10110100
8055 48         pha;c5
8056 F120       sbc ($20),y;($20)=1010,y=20,,,1030<9a c5-9a-1=2a c=1
8058 08         php;35 00110101
8059 48         pha;2a
805A BA         tsx;stack pointer to x
805B 8631       stx $31;e9
805D        ;
805D        ;check data set
805D A92A       lda #$2a
805F 8540       sta $40
8061 A901       lda #$01
8063 8541       sta $41
8065 A9C5       lda #$c5
8067 8542       sta $42
8069 A980       lda #$80
806B 8543       sta $43
806D A93D       lda #$3d
806F 8544       sta $44
8071 A941       lda #$41
8073 8545       sta $45
8075 A993       lda #$93
8077 8546       sta $46
8079 A981       lda #$81
807B 8547       sta $47
807D A9C8       lda #$c8
807F 8548       sta $48
8081 A980       lda #$80
8083 8549       sta $49
8085 A940       lda #$40
8087 854A       sta $4a
8089 A901       lda #$01
808B 854B       sta $4b
808D A9FD       lda #$fd
808F 854C       sta $4c
8091 A980       lda #$80
8093 854D       sta $4d
8095 A953       lda #$53
8097 854E       sta $4e
8099 A941       lda #$41
809B 854F       sta $4f
809D A987       lda #$87
809F 8550       sta $50
80A1 A981       lda #$81
80A3 8551       sta $51
80A5        ;
80A5        ;check start
80A5 A211       ldx #$11
80A7 A0FB       ldy #$fb
80A9        loop:
80A9 B90001     lda $0100,y
80AC 29C3       and #$c3;stack
80AE D540       cmp $40,x
80B0 D00D       bne err
80B2 88         dey
80B3 CA         dex
80B4 B90001     lda $0100,y
80B7 D540       cmp $40,x;code
80B9 D004       bne err
80BB 88         dey
80BC CA         dex
80BD 10EA       bpl loop;end if x=ff
80BF        ;check end
80BF        err:
80BF 8632       stx $32
80C1 8433       sty $33
80C3 8535       sta $35
80C5 B540       lda $40,x
80C7 8534       sta $34
80C9 DB         stp
80CA        ;end
65c02test19.binをロードしました。
念のため先に/DM 00でゼロページの値を確認しました。


/RUNを実行しました。

0030にはプログラムの実行を開始したときのスタックポインタの値(FD)が入ります。
0031にはプログラムを終了したときのスタックポインタの値(E9)が入ります。
計算結果が想定した結果と全て一致したときは0032にはFFが入り0033にはE9が入ります。
不一致があった場合には0032にはカウントダウン値(Xレジスタ)が入り0033にはそのときのスタックアドレスが入ります。
さらに0034には比較した正しい値が入り0035には間違った値が入ります。

参考までに。
スタックの内容です。


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

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