14 |
6809の割込み動作 |
メインCPUとサブCPUはお互いに割込みを掛け合います。メインCPUからは通常、サブCPUのbusyを確認し、readyであればサブCPUをHALTし、共有メモリにコマンドを書き込んだ後、HALTをネゲートします。サブCPUはすぐにbusyにした後、コマンドを解析し、処理を行います。
これが通常シーケンスですが、例えば時間のかかる処理をサブCPUがやっていた場合に中止させたい時には割込みをかけるしかありません。これをCANCEL割込みといいます。逆に、サブCPUからメインCPUに用事がある場合にはATTENTION割込みをかけます。
さて、メインCPUの割込みの一つにタイマー割込みがあり、これをシミュレーションしてみます。タイマー割り込みはIRQに接続されているため、IRQ割り込みハンドラをプログラムします。IRQは全レジスタのセーブリストアが自動で行われます。割り込みハンドラでは、まずタイマ割り込み要因のクリアを行った後、要因レジスタは負論理であるため、反転してメモリに書きだした後でRTIで元の命令列に戻ります。
1000 stack equ \$1000
2000 ustack equ \$2000
FE00 start org \$fe00
FE00 10CE1000 lds #stack
FE04 CE2000 ldu #ustack
FE07 8EFD02 ldx #\$FD02 ; IRQ Mask Reg
FE0A 86FF lda #\$FF ; Timer IRQ unmask
FE0C A784 sta ,X ; Timer IRQ enabled
FE0E 20FE bra *
FE10 firq equ *
FE10 irq equ *
FE10 8EFD03 ldx #\$FD03 ; IRQ event reg
FE13 A684 lda ,X ; IRQ clear
FE15 8AFB ora #\$FB
FE17 70FE17 eora #\$FF
FE1A B73000 sta \$3000
FE1D 3B rti
FFF6 org \$fff6
FFF6 FE10 fdb firq
FFF8 org \$fff8
FFF8 FE10 fdb irq ; Timer IRQ
FFFE org \$fffe
FFFE FE00 fdb start
0000 end
まずリセット後にFD02をライトし、割込みマスクを許可します。'1'をライトすると許可となります。
次にタイマー割込みがかかるとスタックに全レジスタを退避します。PC, US, IY, IX, DP, B, A, CCの12バイトです。
次に\$FFF8から2バイトをフェッチします。ところが、\$FFF8の示すアドレスにジャンプする前に再度全レジスタをスタックに退避しています。
割込みが入った場合、直ちに割込みマスクがかからなければ、無限に割込みが入るので、これはCPUのIRQマスクのバグと思われます。