WonderWitch サンプル:割り込み
サンプル 1:H-BLANK 割り込み
intr1.lzh:1,945 Bytes(00/09/07)
割り込みの設定には、いくつか専門的な知識を要求される。
特に 80x86 特有の「セグメント」に関する知識が無いと、
何の設定をやっているのかわからないかもしれない。
しかし形式さえ覚えれば、それほど問題なく使えると思う。
まずコールバック関数を作る。このサンプルでは hIntCallback()
がそれである。コールバック関数は far コールされるので、
関数名の前に far
を付けておく。
次に sys_interrupt_set_hook()
でコールバック関数を登録する。構造体 intvector_t
の各メンバを設定するのだが、これがまたややこしい。
- メンバ
callback
だが、
これにはコールバック関数のオフセット値を設定する。ようするに
(void (near *)(void))FP_OFF(hIntCallback)
を設定してやればいい。FP_OFF()
はオフセット値を取り出すマクロで、
それを関数ポインタにキャストしている。
ちなみにセグメント値を取り出すマクロは FP_SEG()
である。
- メンバ
cs
と ds
には、
コールバック関数を呼び出す際の CS と DS を設定する。
これはインラインアセンブラ機能を使って直接代入する。
_CS
と _DS
は、
サンプルの頭の方で #define
を使って定義している。
- メンバ
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
回の割り込みがかかる。