[新連載開始]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
|

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
前へ
次へ
ホームページトップへ戻る