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


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

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

[第52回]



●CMP,CPX,CPY(2)テストプログラム

前回の説明の一部に誤りがありましたので訂正いたしました。

CMPのテストプログラムです。
下がアセンブラソースプログラムです。
;w65c02test25 26/8/10
;
;CMP
;
        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
;
        ldx #$fd;stack pointer
        txs
;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
;
        cmp $1000;9a-12=88 n=1 c=1
        php;b5 10110101
        lda #$87
        cmp $1000,x;87-34=53 c=1
        php;35 00110101
        lda #$53
        cmp $1000,y;53-56=fd n=1 c=0
        php;b4 10110100
        lda #$fd
        cmp #$bc;fd-bc=41 c=1
        php;35 00110101
        lda #$40
        cmp $10;40-78=c8 n=1 c=0
        php;b4 10110100
        lda #$c8
        cmp ($10,x);20,21,,,1010<34,,,(zp,x) c8-34=94 n=1 c=1
        php;b5 10110101
        lda #$93
        cmp ($22);22,23,,,1020<56,,,(zp) 93-56=3d c=1
        php;35 00110101
        lda #$3d
        cmp $00,x;,,,10<78,,,zp,x 3d-78=c5 n=1 c=0
        php;b4 10110100
        lda #$c5
        cmp ($20),y;($20)=1010,y=20,,,1030<9a c5-9a=2b c=1
        php;35 00110101
;
        cpx $1000;10-12=fe n=1 c=0
        php;b4 10110100
        cpx #$bc;10-bc=54 c=0
        php;34 00110100
        cpx $10;10-78=98 n=1 c=0
        php;b4 10110100
;
        cpy $1000;20-12=0e c=1
        php;35 00110101
        cpy #$bc;20-bc=64 c=0
        php;34 00110100
        cpy $10;20-78=a8 n=1 c=0
        php;b4 10110100
        tsx;stack pointer to x
        stx $31;e9
;
;check data set
        lda #$80
        sta $40
        lda #$00
        sta $41
        lda #$01
        sta $42
        lda #$80
        sta $43
        lda #$00
        sta $44
        lda #$80
        sta $45
        lda #$01
        sta $46
        lda #$80
        sta $47
        lda #$01
        sta $48
        lda #$81
        sta $49
        lda #$80
        sta $4a
        lda #$01
        sta $4b
        lda #$80
        sta $4c
        lda #$01
        sta $4d
        lda #$81
        sta $4e
;
;check start
        ldx #$0e
        ldy #$fd
loop:
        lda $0100,y
        and #$83;stack
        cmp $40,x
        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

W65C02アセンブラでアセンブルしました。

下はアセンブルした結果作成されたアセンブルリストです。

0000        ;w65c02test25 26/8/10
0000        ;
0000        ;CMP
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 A2FD       ldx #$fd;stack pointer
8002 9A         txs
8003        ;set data
8003 A210       ldx #$10
8005 A020       ldy #$20
8007 A912       lda #$12
8009 8D0010     sta $1000;1000<12,,,a
800C A934       lda #$34
800E 9D0010     sta $1000,x;1010<34,,,a,x
8011 A956       lda #$56
8013 990010     sta $1000,y;1020<56,,,a,y
8016 A978       lda #$78
8018 8510       sta $10;10<78,,,zp
801A A910       lda #$10
801C 9510       sta $10,x;20<10,,,(zp,x)
801E 9511       sta $11,x;21<10,,,1010
8020 8523       sta $23;23<10,,,(zp)
8022 A920       lda #$20
8024 8522       sta $22;22<20,,,1020
8026            ;$00,x,,,10<78 zp,x
8026            ;zp=10,(zp)=1010,(zp),y=1030
8026 A99A       lda #$9a
8028 8D3010     sta $1030
802B        ;
802B        ;start
802B BA         tsx;stack pointer to x
802C 8630       stx $30
802E        ;
802E A99A       lda #$9a
8030 A210       ldx #$10
8032 A020       ldy #$20
8034        ;
8034 CD0010     cmp $1000;9a-12=88 n=1 c=1
8037 08         php;b5 10110101
8038 A987       lda #$87
803A DD0010     cmp $1000,x;87-34=53 c=1
803D 08         php;35 00110101
803E A953       lda #$53
8040 D90010     cmp $1000,y;53-56=fd n=1 c=0
8043 08         php;b4 10110100
8044 A9FD       lda #$fd
8046 C9BC       cmp #$bc;fd-bc=41 c=1
8048 08         php;35 00110101
8049 A940       lda #$40
804B C510       cmp $10;40-78=c8 n=1 c=0
804D 08         php;b4 10110100
804E A9C8       lda #$c8
8050 C110       cmp ($10,x);20,21,,,1010<34,,,(zp,x) c8-34=94 n=1 c=1
8052 08         php;b5 10110101
8053 A993       lda #$93
8055 D222       cmp ($22);22,23,,,1020<56,,,(zp) 93-56=3d c=1
8057 08         php;35 00110101
8058 A93D       lda #$3d
805A D500       cmp $00,x;,,,10<78,,,zp,x 3d-78=c5 n=1 c=0
805C 08         php;b4 10110100
805D A9C5       lda #$c5
805F D120       cmp ($20),y;($20)=1010,y=20,,,1030<9a c5-9a=2b c=1
8061 08         php;35 00110101
8062        ;
8062 EC0010     cpx $1000;10-12=fe n=1 c=0
8065 08         php;b4 10110100
8066 E0BC       cpx #$bc;10-bc=54 c=0
8068 08         php;34 00110100
8069 E410       cpx $10;10-78=98 n=1 c=0
806B 08         php;b4 10110100
806C        ;
806C CC0010     cpy $1000;20-12=0e c=1
806F 08         php;35 00110101
8070 C0BC       cpy #$bc;20-bc=64 c=0
8072 08         php;34 00110100
8073 C410       cpy $10;20-78=a8 n=1 c=0
8075 08         php;b4 10110100
8076 BA         tsx;stack pointer to x
8077 8631       stx $31;e9
8079        ;
8079        ;check data set
8079 A980       lda #$80
807B 8540       sta $40
807D A900       lda #$00
807F 8541       sta $41
8081 A901       lda #$01
8083 8542       sta $42
8085 A980       lda #$80
8087 8543       sta $43
8089 A900       lda #$00
808B 8544       sta $44
808D A980       lda #$80
808F 8545       sta $45
8091 A901       lda #$01
8093 8546       sta $46
8095 A980       lda #$80
8097 8547       sta $47
8099 A901       lda #$01
809B 8548       sta $48
809D A981       lda #$81
809F 8549       sta $49
80A1 A980       lda #$80
80A3 854A       sta $4a
80A5 A901       lda #$01
80A7 854B       sta $4b
80A9 A980       lda #$80
80AB 854C       sta $4c
80AD A901       lda #$01
80AF 854D       sta $4d
80B1 A981       lda #$81
80B3 854E       sta $4e
80B5        ;
80B5        ;check start
80B5 A20E       ldx #$0e
80B7 A0FD       ldy #$fd
80B9        loop:
80B9 B90001     lda $0100,y
80BC 2983       and #$83;stack
80BE D540       cmp $40,x
80C0 D004       bne err
80C2 88         dey
80C3 CA         dex
80C4 10F3       bpl loop;end if x=ff
80C6        ;check end
80C6        err:
80C6 8632       stx $32
80C8 8433       sty $33
80CA 8535       sta $35
80CC B540       lda $40,x
80CE 8534       sta $34
80D0 DB         stp
80D1        ;end

CMP、CPX、CPYの動作確認をアドレッシングモードを変えながら行なうために適当な初期値をセットしメモリアドレスにもセットしてプログラムを開始します。
CMPはA(アキュムレータ)とM(メモリ、即値)との大小を比較する演算ですが結果のフラグはSBC A−Mを実行したときと同じになります(A、Mの値は変わりません)。
大小の比較によってフラグがどう変わるかを確認するためにアキュムレータの値を変えながらCMPを実行します。
フラグの確認をするのがプログラムの目的ですからCMPの後でフラグをスタックにプッシュします。
実行後にスタックを確認すればよいのですがそれだけではなかなか理解が進みません。
各行の後ろに変化するフラグをコメントとして書きましたがやってみると思い違いなどがあって何回か試行しながら直しました。
コメントそのものが正しいかどうかを確認するためもあって実行後にスタックにプッシュしたフラグをチェックするプログラムを追加しました。
試行した結果確認した正しいフラグの値を$40〜$4Eにストアしました。
その値とスタックにプッシュした値とを比較します。
比較するフラグはN、Z、Cだけですからスタックから戻したフラグ値はそれ以外のビットをマスクしてから比較を行ないます。
ここでもCMPを実行しています。
ここでは一致するかどうかのチェックですからZフラグのみを見ます。
不一致のときはerr:に行きます。ループカウンタにはXレジスタをダウンカウンタとして使います。
X=0までループします。
X<0でループから出ます。
出た先はerr:と同じですが$32の値によって正しく終了したかエラーがあったかが判断できます。
$30にはプログラム開始時のスタックポインタの値(FD)が入ります。
$31にはプログラム終了時のスタックポインタの値が入ります。
チェックの結果が全て正しければ$32にFFが入ります。
$33には終了時のスタックポインタの値が入ります。
チェックでエラーがあればそのときの比較データが$34に入り、フラグの値が$35に入ります。

65c02test25.binをロードして実行しました。

実行後に$30〜の値を確認しました。
$30がFD、$31はEEになっています。
$32はFFなので比較が正しく終了したことがわかります。

念のため/DM 01でスタックエリアを表示しました。


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

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