メイン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'をライトすると許可となります。
 図148.1 割込みイネーブルのタイミングチャート
図148.1 割込みイネーブルのタイミングチャート
次にタイマー割込みがかかるとスタックに全レジスタを退避します。PC, US, IY, IX, DP, B, A, CCの12バイトです。
 図148.2 レジスタ退避のタイミングチャート
図148.2 レジスタ退避のタイミングチャート
次に\$FFF8から2バイトをフェッチします。ところが、\$FFF8の示すアドレスにジャンプする前に再度全レジスタをスタックに退避しています。
 図148.3 割込みベクタフェッチのタイミングチャート
図148.3 割込みベクタフェッチのタイミングチャート
割込みが入った場合、直ちに割込みマスクがかからなければ、無限に割込みが入るので、これはCPUのIRQマスクのバグと思われます。
 前のブログ
次のブログ
前のブログ
次のブログ