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


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

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