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


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

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

[第40回]



●LDA,LDX,LDY,STA,STX,STY テストプログラム

W65C02のLD命令、ST命令はアドレッシングモードが沢山あって理解するのにも一苦労します。
ことにLDAやSTAはもうアドレッシングモードのオンパレードです。
こんなに沢山のアドレッシングモードが要るのかいなとちょっと疑問に思ってしまいます。
ですけれどそれをぼやいてみたってどうなるものではありません。
とんでもないCPUに首を突っ込んでしまったわが身を呪いつつW65C02アセンブラを作っていきました。
なんとか作ったものの本当にこれで正しくコードに変換できるのか、そもそもまともにアセンブラニーモニックが解読できるのか、そこはしっかりテストをしなければなりません。
ということでテストプログラムを作りかけたのですけれど一体どうやって全てのアドレッシングモードを網羅するプログラムを作ったらよいのかしばし悩んでしまいました。
作りかけて大体のところが出来たあたりで後悔いたしました。
本当は小さく分けてちまちまとアドレッシングモードごとにテストするプログラムを作るべきだったのです。
後悔先に立たず。
まともにできているのかどうなのかを確認すること自体が困難な実に不出来なプログラムになってしまいました。
各命令を落とすことなく実行したことがわかるように途中に適当な演算などをはさんで特定のアドレスに結果が書き込まれるように工夫しました。
実行後に結果の値をチェックしてとにかくテストプログラムとしては正しく実行されたことは確認できました。
それにしても面倒なプログラムです。
おそらく数日もしたら何をやっているのかわからなくなってしまいそうな。
それでとにかく後日実行しても正しく機能していることが確認できるようにプログラムの後半部分にプログラムで結果をチェックする部分を追加しました。
下は最終的にチェック自体をプログラムで行なうように後ろにチェック部分を追加して作ったプログラムです。
;w65c02test14 26.7.31 8.7
;
;LDA,LDX,LDY,STA,STX,STY
;
        org $8000
;
        stz $00
        lda #$12;LDA # 12
        ldx #$34;LDX # 34
        ldy #$56;LDY # 56
        sta $01;STA zp 12
        stx $02;STX zp 34
        sty $03;STY zp 56
        lda $01;LDA zp 12
        ldx $02;LDZ zp 34
        ldy $03;LDY zp 56
        sta $1000;STA a 12
        stx $1001;STX a 34
        sty $1002;STY a 56
        lda $02;34
        sta $1000,x;STA a,x 1034<34
        lda $03;56
        sta $1000,y;STA a,y 1056<56
        lda $1000,x;LDA a,x 1034=34
        sta $04;34
        lda $1000,y;LDA a,y 1056=56
        sta $05;56
        lda #$78
        sta $12,x;STA zp,x 46<78
        lda #$20
        sta $09
        lda #$10
        sta $0a
        sta ($09);STA (zp) 1020<10
        lda #$30
        sta $44
        lda #$10
        sta $45
        sta ($10,x);STA (zp,x) 1030<10
        sta ($09),y;STA (zp),y  1020+56=1076<10
        stx $20,y;STX zp,y 76<34
        sty $21,x;STY zp,x 55<56
        lda $1000;LDA a 12
        ldx $1001;LDX a 34
        ldy $1002;LDY a 56
        sta $06;12
        stx $07;34
        sty $08;56
;
        lda ($09);LDA (zp) 1020=10
        sta $0b;10
        lda $12,x;LDA zp,x 46=78
        sta $0c;78
        lda ($10,x);LDA (zp,x) 1030=10
        sta $0d;10
        lda ($09),y;LDA (zp),y 1076=10
        sta $0e;10
        ldx $20,y;LDX zp,y 76=34
        stx $0f;34
        sta $1056;10
        ldx $1000,y;LDX a,y 1056=10
        stx $10;10
        ldy $36,x;LDY zp,x 46=78
        sty $11;78
        ldy $1024,x;LDY a,x 1034=34
        sty $12;34
        lda $55;56
        sta $13;56
;
;check
        lda #$34
        sta $24
        lda #$56
        sta $25
        lda #$12
        sta $26
        lda #$34
        sta $27
        lda #$56
        sta $28
;
        lda #$10
        sta $2b
        lda #$78
        sta $2c
        lda #$10
        sta $2d
        sta $2e
        lda #$34
        sta $2f
        lda #$10
        sta $30
        lda #$78
        sta $31
        lda #$34
        sta $32
        lda #$55
        sta $33
;
        ldx #$04
        ldy #$05
loop1:
        lda $00,x
        cmp $20,x
        bne err
        inx
        dey
        bne loop1
;
        ldx #$0b
        ldy #$08
loop2:
        lda $00,x
        cmp $20,x
        bne err
        inx
        dey
        bne loop2
err:
        stx $40;if err,adrs on err
        sty $41;if err,not zero
        stp
;end
W65C02アセンブラでアセンブルしました。

200バイトを越えるプログラムになってしまいました。
下はW65C02アセンブラでアセンブルして生成されたアセンブルリストです。
0000        ;w65c02test14 26.7.31 8.7
0000        ;
0000        ;LDA,LDX,LDY,STA,STX,STY
0000        ;
8000            org $8000
8000        ;
8000 6400       stz $00
8002 A912       lda #$12;LDA # 12
8004 A234       ldx #$34;LDX # 34
8006 A056       ldy #$56;LDY # 56
8008 8501       sta $01;STA zp 12
800A 8602       stx $02;STX zp 34
800C 8403       sty $03;STY zp 56
800E A501       lda $01;LDA zp 12
8010 A602       ldx $02;LDZ zp 34
8012 A403       ldy $03;LDY zp 56
8014 8D0010     sta $1000;STA a 12
8017 8E0110     stx $1001;STX a 34
801A 8C0210     sty $1002;STY a 56
801D A502       lda $02;34
801F 9D0010     sta $1000,x;STA a,x 1034<34
8022 A503       lda $03;56
8024 990010     sta $1000,y;STA a,y 1056<56
8027 BD0010     lda $1000,x;LDA a,x 1034=34
802A 8504       sta $04;34
802C B90010     lda $1000,y;LDA a,y 1056=56
802F 8505       sta $05;56
8031 A978       lda #$78
8033 9512       sta $12,x;STA zp,x 46<78
8035 A920       lda #$20
8037 8509       sta $09
8039 A910       lda #$10
803B 850A       sta $0a
803D 9209       sta ($09);STA (zp) 1020<10
803F A930       lda #$30
8041 8544       sta $44
8043 A910       lda #$10
8045 8545       sta $45
8047 8110       sta ($10,x);STA (zp,x) 1030<10
8049 9109       sta ($09),y;STA (zp),y  1020+56=1076<10
804B 9620       stx $20,y;STX zp,y 76<34
804D 9421       sty $21,x;STY zp,x 55<56
804F AD0010     lda $1000;LDA a 12
8052 AE0110     ldx $1001;LDX a 34
8055 AC0210     ldy $1002;LDY a 56
8058 8506       sta $06;12
805A 8607       stx $07;34
805C 8408       sty $08;56
805E        ;
805E B209       lda ($09);LDA (zp) 1020=10
8060 850B       sta $0b;10
8062 B512       lda $12,x;LDA zp,x 46=78
8064 850C       sta $0c;78
8066 A110       lda ($10,x);LDA (zp,x) 1030=10
8068 850D       sta $0d;10
806A B109       lda ($09),y;LDA (zp),y 1076=10
806C 850E       sta $0e;10
806E B620       ldx $20,y;LDX zp,y 76=34
8070 860F       stx $0f;34
8072 8D5610     sta $1056;10
8075 BE0010     ldx $1000,y;LDX a,y 1056=10
8078 8610       stx $10;10
807A B436       ldy $36,x;LDY zp,x 46=78
807C 8411       sty $11;78
807E BC2410     ldy $1024,x;LDY a,x 1034=34
8081 8412       sty $12;34
8083 A555       lda $55;56
8085 8513       sta $13;56
8087        ;
8087        ;check
8087 A934       lda #$34
8089 8524       sta $24
808B A956       lda #$56
808D 8525       sta $25
808F A912       lda #$12
8091 8526       sta $26
8093 A934       lda #$34
8095 8527       sta $27
8097 A956       lda #$56
8099 8528       sta $28
809B        ;
809B A910       lda #$10
809D 852B       sta $2b
809F A978       lda #$78
80A1 852C       sta $2c
80A3 A910       lda #$10
80A5 852D       sta $2d
80A7 852E       sta $2e
80A9 A934       lda #$34
80AB 852F       sta $2f
80AD A910       lda #$10
80AF 8530       sta $30
80B1 A978       lda #$78
80B3 8531       sta $31
80B5 A934       lda #$34
80B7 8532       sta $32
80B9 A955       lda #$55
80BB 8533       sta $33
80BD        ;
80BD A204       ldx #$04
80BF A005       ldy #$05
80C1        loop1:
80C1 B500       lda $00,x
80C3 D520       cmp $20,x
80C5 D012       bne err
80C7 E8         inx
80C8 88         dey
80C9 D0F6       bne loop1
80CB        ;
80CB A20B       ldx #$0b
80CD A008       ldy #$08
80CF        loop2:
80CF B500       lda $00,x
80D1 D520       cmp $20,x
80D3 D004       bne err
80D5 E8         inx
80D6 88         dey
80D7 D0F6       bne loop2
80D9        err:
80D9 8640       stx $40;if err,adrs on err
80DB 8441       sty $41;if err,not zero
80DD DB         stp
80DE        ;end

上のほうでも書きましたが一度に全てのアドレッシングモードをテストしようとしたためになんともよくわからぬプログラムになってしまいました。
実に出来の悪いプログラムの見本です。
やってることは各レジスタの値をアドレッシングモードに従って適当なメモリエリアにSAVE/LOADしているだけです。
そこが複雑になるのでテストの対象にしている命令にコメントをつけて「どのアドレスに」「どういう値」を書いているのかまたは読み出しているのかをメモ書きしています。
書いたり読んだりした結果ゼロページの特定のアドレスに結果の値が書き込まれます。
どこにどんな値が書き込まれるのかは自分自身がCPUになったつもりで命令コードを追いかけて途中の値と最終的な値をメモ書きしました。
あとからプログラムでチェックするために追加したcheck以下で新しい命令cmp zp,xを使っています。
cmp命令のテストにもなりました。
結果の値が全て一致したらそのときのアドレス修飾カウンタXの値が$40に入りループカウンタYの値(=00)が$41に入りストップします。
不一致だったときはそのときのアドレス修飾カウンタXの値が$40に入りループカウンタYの値(ノット0)が$41に入りストップします。

プログラムの実行結果です。

念のためにプログラムの実行前に/dm 00でゼロページの中身を表示させました。
そして/RUNでプログラムを実行したあとでもう一度ゼロページの内容を表示させました。

チェックの結果エラーがなかったときはアドレス41に00が入ります。
エラーがみつかった場合にはアドレス41には途中で停止したカウンタ(Yレジスタ)の値が入り、アドレス40には不一致になったアドレスを示すXレジスタの値が入ります。
正常に完了した場合にはアドレス40にはそのときのXの値(13)が入ります。

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

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