[新連載開始]W65C02マイコンボードの製作
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
私としてはW65C02をさわるのは全く初めてです。何から何まで未経験です。さてどうなりますでしょうか。
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
[第63回]
●NMIB,RTI
NMIB(Non Maskable Interrupt)は命令ではありません。
マスク不能割込みです。
割込みには後の回で説明するIフラグで割込みを禁止できるマスク可能割込みIRQBがありますがNMIB入力信号はIフラグの状態に関係なく受付けられます。
NMIBはW65C02のpinNo.6に入力します。
入力信号の下がりエッジで受付けられます。
NMIB信号が受付けられるとCPUはその時のPC(プログラムカウンタ)とフラグレジスタをスタックに退避してアドレスFFFA、FFFBに書かれたアドレスにジャンプします。
割込み処理中は通常の割込みは禁止されますがNMIBはマスク不能なエッジ入力割込みなので割込み処理中でも重ねて下がりエッジ信号が入力されるとNMIB処理が二重に行なわれることが考えられます。
チャタリングなどの有無などに配慮する必要があります。
NMIBの処理はRTI命令によって完了します。
RTI命令はIRQBの終わりにも使われます。
RTIの実行によってスタックに退避されていたPCとフラグがもとに戻され割込み発生時に待たされていた処理が再開されます。
| ニーモニック | マシン語コード | アセンブラ書式 | バイト数 | クロック数 |
| RTI | 40 | RTI | 1 | 6 |
下はテストプログラムです。
;w65c02test38 26/8/14
;
;NMI,RTI
;
org $8000
;
lda #$10
sta $fffa
lda #$80
sta $fffb
ldx #$fd
txs
sei
bra start
;
int:
iny
sty $04
sty $0200
rti
;
start:
stx $00;sp
lda #$55;for test
sta $04;=led
sta $0200;led
ldy #$55;for test
loop:
nop
nop
inc $02
bra loop
;end
|
このプログラム自体はただ実行しただけではテストになりません。
プログラムの実行中にW65C02のpin6に下がりエッジ信号を入力することで割込み処理が実行されます。
W65C02アセンブラでアセンブルしました。

下はアセンブルした結果作成されたアセンブルリストです。
0000 ;w65c02test38 26/8/14 0000 ; 0000 ;NMI,RTI 0000 ; 8000 org $8000 8000 ; 8000 A910 lda #$10 8002 8DFAFF sta $fffa 8005 A980 lda #$80 8007 8DFBFF sta $fffb 800A A2FD ldx #$fd 800C 9A txs 800D 78 sei 800E 8007 bra start 8010 ; 8010 int: 8010 C8 iny 8011 8404 sty $04 8013 8C0002 sty $0200 8016 40 rti 8017 ; 8017 start: 8017 8600 stx $00;sp 8019 A955 lda #$55;for test 801B 8504 sta $04;=led 801D 8D0002 sta $0200;led 8020 A055 ldy #$55;for test 8022 loop: 8022 EA nop 8023 EA nop 8024 E602 inc $02 8026 80FA bra loop 8028 ;end |
割り込みが受付けられたことが確認できるようにLED出力(アドレス0200)を行なっています。
同時に同じ値をこれも確認のためにゼロページアドレスの$04にも書いています。
当初はプログラムループの中で確認のためにスタックポインタの値をXレジスタに移してそれをゼロページアドレスに書くというようにしたのですがスタックポインタの値がXレジスタに読み込まれませんでした(またはゼロページに書き込まれない?)。
メモリアクセスの問題かと思ってクロックを4MHzに落としてやってみたのですがやはり同じでした。
同じことは割込みプログラム中でゼロページアドレスの値を直接書き換える(inc $xx)という処理でも誤動作が発生しました。
最終的には今回のテストもクロック14MHzで実行して正常動作を確認したのですが上記のようにしたプログラムではクロック4MHzでも駄目でした。
そこにこだわると本来のテストの目的(NMIBのテスト)ができませんのでそこはプログラムリストの通りのプログラムで動作テストを行ないました。
W65C02は命令動作によってメモリアクセスのタイミングが厳しいところがありますからそのことが何か関係しているのかもしれません。
プログラムの実行中に強制的に実行をストップするためRESETとBEをLレベルにするとデータとプログラムの一部が壊れるという事例がありました。
これもメモリアクセスのタイミングが関係しているのかもしれません。
65c02test38.binをロードして/RUNを実行しました。

今までのプログラムと違ってブレイクせずにNMIB入力を待ってループしている状態です。
NMIB信号はPIC18F45C50のRB3から出力します。
回路図は[第16回]にあります。
W65C02TESTボードに搭載しているPIC18F45K50にはPICUSBIOシステムプログラムが入っています。
BASICでI/Oポートを制御することができます。
BASICは普通にプログラムとして組むこともできますが上の画像のようにダイレクトモードを使う事もできます。
picout PORTB,$F7の入力でPORTBのbit3が立ち下がりました。
これでNMIB信号が出力されたことになります。
さらにテストを進めるにはNMIB信号を一度立ち上げなければいけません。
そこでpicout PORTB,$FFを入力しました。
実はテストのためにこの操作は2回行なっています。
画面では1度しか見えませんがPICUSBIOシステムソフトはスクリーンエディタ機能になっていてカーソルを上下させてそこで[Enter]を入力することで繰り返し命令などを入力することができます。
画面では1度だけのように見えますが実際には下のように入力したことになります。
picout PORTB,$F7 NMIB↓
picout PORTB,$FF NMIB↑
picout PORTB,$F7 NMIB↓
picout PORTB,$FF NMIB↑
そのあと/stopを入力してW65C02を停止させました。
/cmコマンドでゼロページの値を確認しました。
アドレス0004にはプログラム開始時に55が入ります。
NMIBが実行されるとその値が+1されます。
それが57ですからNMIBが2回実行されたことがわかります。
下はテスト中のW65C02テストボードです。

LEDにはプログラム開始時に01010101(55)を出力しました。
BASICのpicout命令をダイレクト実行しました。

LEDの表示が01010110(56)になりました。
NMIB信号が受付けられたことがわかります。
BASICダイレクトモードでpicout命令を実行してNMIB信号を一度↑にした後もう一度↓にしました。

LED表示が01010111(57)になりました。
W65C02マイコンボードの製作[第63回]
2026.9.3 upload
前へ
次へ
ホームページトップへ戻る