■
前回書いた割り込み処理の初期化部分を詳しく見てみる。
PCの割り込みコントローラ(Programmable Interrupt Controller:PIC)はIntelの8259Aというチップが二つ使われている(現在はチップセットでエミュレートされている模様)。
8259AへのIOポートはmaster側が「0x20と0x21」、slave側が「0xA0と0xA1」となっている。初期化はこのチップのICW1〜ICW4というレジスタを弄る。意味はそれぞれ以下の通り。
// 8259A master setting //まずは0x20のICW1を設定すると初期化モードになり、その後 //0x21にICW2,3,4の順で書き込んでいく out8(0x20,0x11); //ICW1の設定でICW1は0x20portのbit4を1にして設定する。 //他のbitはそれぞれ以下のような意味 // bit0 ICW4が必要かどうか - 必要なので1 // bit1 8259Aシングルか - 複数なので0 // bit2, 5〜7 8080/8085モードの時だけ必要 - 使わないので0 // 以上から ICW1には 0x11を設定する。 out8(0x21,0x20+0); //ICW2の設定でbit3〜7を使用する //割り込みベクタのベースアドレスを設定する。 //0x20に設定しておくと割り込みIRnが発生した時 //0x20+nの割り込み処理が呼び出される。 out8(0x21,0x04); //ICW3の設定 masterとslaveで意味が異なる //slaveが繋がっているIR0〜IR7のどれかの番号を指定する //PCの場合はIR2に繋がっているので2bit目を指定する out8(0x21,0x01); //ICW4の設定 bit0-4を使用 // bit0 8080/8085モードか8086モードか 8086なので1 // bit1 EOIモード ノーマルEOIか自動EOIか ノーマルなので 0 // bit2-3 バッファモード 使わないので 0 // bit4 特殊ネスト・モードを使うか // 多重割り込みを許可するかどうか 使わないので0 // 8259A slave setting // masterとほぼ意味は同じ out8(0xA0,0x11); out8(0xA1,0x20+8); //masterと重ならないように8ずらしている out8(0xA1,0x02); //ここはmasterとは意味が異なり //IRn番目に繋がっていれば数値nを入力する(bit位置では無い) out8(0xA1,0x01); //初期化終了後の8259Aはそれぞれ // 0x20 bit3-4 = 00の場合 OCW2 // 0x20 bit3-4 = 10の場合 OCW3 // 0x21 OCW1 // の設定となる // mask outport at not key & timer out8(0x21, 0xFC); // OCW1の設定でこれは割り込み入力IR0〜IR7の //どのbitを割り込み禁止にするか決める(1が禁止) //0xFCだとbit0と1のみが割り込み許可 out8(0xA1, 0xFF); //slave側の割り込みは全て禁止 //bit0と1はそれぞれ以下の割り込み //bit0 システム・タイマ //bit1 キーボード
また、割り込み処理のdefaultHandlerに書いたPICへの書き込みは以下のような意味がある
out8(0x20, 0x20) // 0x20への0x20はまずbit3-4が0なのでOCW2への書き込みである。 // OCW2はEOIに関する書き込みをする部分でEOIとはEnd of Interruptの事で割り込みの終了に // 関する設定である。通常のOSでは初期設定でEOIモードをノーマルEOIとするので割り込み終了 // 後に自分で割り込みが終了したことをPICに知らせる必要がある。 // bit0-2は指定EOI時に使用し、それぞれIR0-7に対応(000=IR0 001=IR1...) // bit5-7はEOIに関するコマンドで 001は非指定EOI(この時bit0-2は0) // これより0x20は優先度の高い割り込み終了を知らせ次の割り込みを受け付けられるようにする。