WonderWitch サンプル:割り込み


サンプル 1:H-BLANK 割り込み

intr1.lzh:1,945 Bytes(00/09/07)

割り込みの設定には、いくつか専門的な知識を要求される。 特に 80x86 特有の「セグメント」に関する知識が無いと、 何の設定をやっているのかわからないかもしれない。 しかし形式さえ覚えれば、それほど問題なく使えると思う。

まずコールバック関数を作る。このサンプルでは hIntCallback() がそれである。コールバック関数は far コールされるので、 関数名の前に far を付けておく。

次に sys_interrupt_set_hook() でコールバック関数を登録する。構造体 intvector_t の各メンバを設定するのだが、これがまたややこしい。
  1. メンバ callback だが、 これにはコールバック関数のオフセット値を設定する。ようするに (void (near *)(void))FP_OFF(hIntCallback) を設定してやればいい。FP_OFF() はオフセット値を取り出すマクロで、 それを関数ポインタにキャストしている。
    ちなみにセグメント値を取り出すマクロは FP_SEG() である。

  2. メンバ csds には、 コールバック関数を呼び出す際の CS と DS を設定する。 これはインラインアセンブラ機能を使って直接代入する。 _CS_DS は、 サンプルの頭の方で #define を使って定義している。

  3. メンバ reserve には何も設定しなくていい。
そして sys_interrupt_set_hook() を実行するのだが、その際に以前の設定値が返ってくるので取っておく。 割り込みが不要になったら、この値を使って元に戻す。
なお intvector_t h_int, h_int_bak; の前に static が付いているが、sys_interrupt_set_hook() は far ポインタで受け取るので無くてもいい。 しかしポインタに関するローカル変数には常に static を付けておくと、いわゆる CS!=DS!=SS 問題に遭遇しにくくなる。

さて、もう一つ H-BLANK 割り込みに必要な設定がある。H-BLANK 割り込みは正確には「H-BLANK タイマーカウント終了」割り込みなので、 このタイマー値を設定してやらなければならない。これには timer_enable() を使う。
サンプルでは H-BLANK 12 回ごとに割り込みがかかるようにした。 H-BLANK 周期は 12,000 回/秒なので、これで 1 秒間に 1,000 回の割り込みがかかる。

WonderWitch の部屋に戻る

HOMEホームに戻る