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


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

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

[第43回]



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

前回のプログラムに「プログラムで」確認する部分を追加しました。
前回のプログラムでADC命令が正しく動作していることはゼロページに記録した値によって確認済みです。
しかしW65C02の複雑なアドレッシングモードを全て網羅しようとして詰め込んだため結果の値の確認に難儀するプログラムになってしまいました。
いずれまたCPUの動作確認が必要になったときのためプログラム自身で結果のチェックができるようにしておくことはまんざら無駄でもないだろうと思って追加しました。
下が追加を行なったプログラムです。
check data setから下が追加したチェックプログラムです。
;w65c02test18 26/8/8 8/8
;
;ADC
;
        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
        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
;
;check data set
        lda #$09
        sta $40
        lda #$01
        sta $41
        lda #$6e
        sta $42
        lda #$01
        sta $43
        lda #$f6
        sta $44
        lda #$80
        sta $45
        lda #$a0
        sta $46
        lda #$c0
        sta $47
        lda #$6b
        sta $48
        lda #$01
        sta $49
        lda #$f3
        sta $4a
        lda #$80
        sta $4b
        lda #$36
        sta $4c
        lda #$01
        sta $4d
        lda #$e0
        sta $4e
        lda #$80
        sta $4f
        lda #$ac
        sta $50
        lda #$80
        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
W65C02アセンブラでアセンブルしました。

下はアセンブルした結果作成されたアセンブルリストです。
0000        ;w65c02test18 26/8/8 8/8
0000        ;
0000        ;ADC
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 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        ;
805D        ;check data set
805D A909       lda #$09
805F 8540       sta $40
8061 A901       lda #$01
8063 8541       sta $41
8065 A96E       lda #$6e
8067 8542       sta $42
8069 A901       lda #$01
806B 8543       sta $43
806D A9F6       lda #$f6
806F 8544       sta $44
8071 A980       lda #$80
8073 8545       sta $45
8075 A9A0       lda #$a0
8077 8546       sta $46
8079 A9C0       lda #$c0
807B 8547       sta $47
807D A96B       lda #$6b
807F 8548       sta $48
8081 A901       lda #$01
8083 8549       sta $49
8085 A9F3       lda #$f3
8087 854A       sta $4a
8089 A980       lda #$80
808B 854B       sta $4b
808D A936       lda #$36
808F 854C       sta $4c
8091 A901       lda #$01
8093 854D       sta $4d
8095 A9E0       lda #$e0
8097 854E       sta $4e
8099 A980       lda #$80
809B 854F       sta $4f
809D A9AC       lda #$ac
809F 8550       sta $50
80A1 A980       lda #$80
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

W65C02はスタックエリアが0100〜01FFに決っていてリセット後はスタックポインタはFDにセットされます(これには注意が必要です。それについては後の方で説明をするつもりです)。
前回のプログラムではフラグと演算結果の値をスタックにPUSHしていきましたが今回のチェックプログラム部分ではスタックをPOP(W65C02ではPULLといいます)するのではなくて直接スタックエリア(0100〜01FF)を参照するようにプログラムしました。
スタック先頭の01FD、01FCの値は確認のための値数なのでチェックはその次の01FBから開始しています。
フラグはN、V、Z、C以外は余計なのでANDでマスクしてからCMPでチェック値と比較しました。
80ACのコメントがstackになっていますがflagの間違いです。
フラグはそのようにマスクしてから比較しますが演算結果の値はそのままの値を比較します。
なので比較はスタックと結果の値の2回行なうことになります。
こういうプログラムのループは大抵カウント値が0になるまでループする形にすることが一般的ですがW65C02のINC、DECはZフラグだけではなくてNフラグもON/OFFするのでそれを利用してBPLでループしています。
BPLはbranch on result plusです。
DEXの結果X=FFになったらループから抜けます。
65c02test18b.binをロードして実行しました。

前回のプログラムと同じで0030にはプログラム開始時のスタックポインタの値FDが、0031にはプログラム終了時の値E9が書き込まれています。
チェックの過程でエラーがみつかった場合には0032にXの値が、0033にそのときの誤データの値が書き込まれます。
正常に完了した場合には0032はFFになります。

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

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