0から作るソフトウェア開発
日々勉強中。。。 |
Follow @Nina_Petipa |
0から作るOS開発 割り込みその3 PICのまとめとPIT |
/* _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ Description : 8259A programmable interrupt master controller _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ */
#define PORT_MASTER_PIC_COMMAND 0x0020 #define PORT_MASTER_PIC_STATUS 0x0020 #define PORT_MASTER_PIC_DATA 0x0021 #define PORT_MASTER_PIC_IMR 0x0021
/* _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ Description :8259A programmable interrupt slave controller _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ */
#define PORT_SLAVE_PIC_COMMAND 0x00A0 #define PORT_SLAVE_PIC_STATUS 0x00A0 #define PORT_SLAVE_PIC_DATA 0x00A1 #define PORT_SLAVE_PIC_IMR 0x00A1
/* _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ PIC Initialization control word _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ */ /* ============================================================================== Description :initialization control word 1 bit number value description 0 IC4 0:PIC does not expect ICW4 command 1:PIC expects ICW4 command 1 SNGL 0:There are some PICs cascaded with each other 1:There is a one PIC on a system 2 ADI 0:Call address interval is 8 1:Call address interval is 4( ignored by x86 system ) 3 LTIM 0:PIC operates in edge trigger mode 1:PIC operates in level trigger mode 4 1 reserved. must be set to 1 5...7 0 Must be 0 in x86 system ============================================================================== */
#define PIC_ICW1 0x11
/* ============================================================================== Description :initialization control word 2 bit number value description 0-2 IVA Address bits for IVT when in MCS-80/85 mode (MCS-80/85) 3-7 IVA specifies the interrupt vector address in x86 (x86) ============================================================================== */
#define PIC_MASTER_ICW2 0x20 /* IRQ0 is mapped to IVT 0x20 */ #define PIC_SLAVE_ICW2 0x28 /* IRQ8 is mapped to IVT 0x28 */
/* =============================================================================== Description :initialization control word 3 bit number value description 0-7 0-7 IRQ0-IRQ7 Master IRQ2 is conected to Slave INT =============================================================================== */
#define PIC_MASTER_ICW3 0x04 #define PIC_SLAVE_ICW3 0x02
/* =============================================================================== Description :initialization control word 4 bit number value description 0 uPM 0:x86 mode 1:MCS-80/85 mode 1 AEOI 0:auto EOI mode 1:manual EOI mode 2 M/S 0:buffered slave 1:buffered master 3 BUF 0:normal mode 1:buffered mode 4 SFNM 0:non nested mode 1:nested mode 5...7 0 Must be 0 =============================================================================== */
#define PIC_MASTER_ICW4 0x01 #define PIC_SLAVE_ICW4 0x01
/* _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ Funtion :initPIC Input :void Output :void Return :void Description :initialize pics _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ */
void initPIC( void ) {
/* --------------------------------------------------------------------- */ /* send ICW1 ot PIC */ /* --------------------------------------------------------------------- */
outPortByte( PORT_MASTER_PIC_COMMAND, PIC_ICW1 ); outPortByte( PORT_SLAVE_PIC_COMMAND, PIC_ICW1 );
/* --------------------------------------------------------------------- */ /* send ICW2 ot PIC */ /* --------------------------------------------------------------------- */
outPortByte( PORT_MASTER_PIC_DATA, PIC_MASTER_ICW2 ); outPortByte( PORT_SLAVE_PIC_DATA, PIC_SLAVE_ICW2 );
/* --------------------------------------------------------------------- */ /* send ICW3 ot PIC */ /* --------------------------------------------------------------------- */
outPortByte( PORT_MASTER_PIC_DATA, PIC_MASTER_ICW3 ); outPortByte( PORT_SLAVE_PIC_DATA, PIC_SLAVE_ICW3 );
/* --------------------------------------------------------------------- */ /* send ICW4 ot PIC */ /* --------------------------------------------------------------------- */
outPortByte( PORT_MASTER_PIC_DATA, PIC_MASTER_ICW4 ); outPortByte( PORT_SLAVE_PIC_DATA, PIC_SLAVE_ICW4 ); }
IRQと割り込みベクタ | ||
---|---|---|
ベクタ番号 | IRQ | 説明 |
32(0x20) | IRQ0 | タイマ |
33(0x21) | IRQ1 | キーボード |
34(0x22) | IRQ2 | スレーブPIC |
35(0x23) | IRQ3 | シリアルポート2 |
36(0x24) | IRQ4 | シリアルポート1 |
37(0x25) | IRQ5 |
ATシステム:パラレルポート2 PS/2システム:予約 |
38(0x26) | IRQ6 | FDD |
39(0x27) | IRQ7 | パラレルポート1 |
40(0x28) | IRQ8(IRQ0) | CMOS RTC(リアルタイムクロック) |
41(0x29) | IRQ9(IRQ1) | CGA 垂直トレース |
42(0x2A) | IRQ10(IRQ2) | 予約 |
43(0x2B) | IRQ11(IRQ3) | 予約 |
44(0x2C) | IRQ12(IRQ4) |
ATシステム:予約 PS/2システム:AUXデバイス |
45(0x2D) | IRQ13(IRQ5) | FPU(浮動小数点演算装置) |
46(0x2E) | IRQ14(IRQ6) | HDD |
47(0x2F) | IRQ15(IRQ7) | 予約 |
/* _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ PIC Operation Control Word _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ */ /* ============================================================================== Description :interrupt mask register bit number value description 0...7 IMR0-7 Interrupt Mask Register bit ============================================================================== */
#define PIC_IMR_MASK_IRQ0 0x01 #define PIC_IMR_MASK_IRQ1 0x02 #define PIC_IMR_MASK_IRQ2 0x04 #define PIC_IMR_MASK_IRQ3 0x08 #define PIC_IMR_MASK_IRQ4 0x10 #define PIC_IMR_MASK_IRQ5 0x20 #define PIC_IMR_MASK_IRQ6 0x40 #define PIC_IMR_MASK_IRQ7 0x80 #define PIC_IMR_MASK_IRQ_ALL 0xFF
/* _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ Funtion :initPIC Input :void Output :void Return :void Description :initialize pics _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ */
void initPIC( void ) {
/* PIC 初期化関数続き */ /* --------------------------------------------------------------------- */ /* send IMR ot PIC */ /* --------------------------------------------------------------------- */
outPortByte( PORT_MASTER_PIC_IMR, (~PIC_IMR_MASK_IRQ0) & (~PIC_IMR_MASK_IRQ2 ) ); outPortByte( PORT_SLAVE_PIC_IMR, PIC_IMR_MASK_IRQ_ALL ); }
PIT(Programmable Interval Timer) |
8259Aのピンアサイン | |||
---|---|---|---|
シンボル | ピン番号 | 名称 | 説明 |
D0-D7 | 1-8 | 双方向データバス |
8ビットのデータバスです CPUは8259Aと8ビットのデータを読み書きできます |
CLK0、CLK1、CLK2 | 9、15、18 | クロック入力 |
入力されたクロックの周波数に基づいて カウンタをカウントしていきます カウンタは3つありますので、入力クロック数も3つあります |
OUT0、OUT1、OUT2 | 10、13、17 | データアウトプット |
データを出力するピンです PITをプログラムすることで出力を変えることができます |
GATE0、GATE1、GATE2 | 11、14、16 | ゲートデータ | クロック入力のゲートとして機能します |
GND | 12 | グラウンド | グラウンド |
VCC | 24 | 電源 | +5Vを入力します |
CS | 1 |
チップセレクト (Lowアクティブ) |
CPUとデータをやり取りするICを決定する信号です この信号がLowのとき8253はデータを入出力できます |
WR | 2 |
ライト (Lowアクティブ) |
CSピンがLowで、WRもLowの場合CPUが8253に データを書き込むことができます OUT命令を使用した場合にCSとWRがLowになります |
RD | 3 |
リード (Lowアクティブ) |
CSピンがLowで、RDもLowの場合CPUは8253から データを読み込むことができます IN命令を使用したときにCSとRDがLowになります |
A0、A1 | 19、20 | アドレスライン |
システムアドレスバスに接続されていて どのカウンタにアクセスするか選択できます |
GATEピンの入力と8253の動作 | |||
---|---|---|---|
モード | Low(Lowエッジ) | Highエッジ | High |
0 | カウント無効 | - | カウント有効 |
1 | - |
1.カウンタ初期化 2.次のクロックでOUTをリセット |
- |
2 |
1.カウント無効 2.直ぐにOUTをHighにします |
1.カウンタを再設定 2.カウンタを初期化 |
カウント有効 |
3 |
1.カウント無効 2.直ぐにOUTをHighにします |
カウンタを初期化 | カウント有効 |
4 | カウント無効 | - | カウント有効 |
5 | - | カウンタ初期化 | - |
パルスの周波数 = CLKの入力クロック周波数 / カウンタの値n
カウンタの値n = CLKの入力クロック周波数 / パルスの周波数
1ms周期のカウンタの値n = 1193181.666...Hz / 1000Hz
8253のレジスタ | ||
---|---|---|
ポートアドレス | レジスタ | 説明 |
0x40 | Counter0 |
カウンタ0に値を設定するレジスタです 読み込み時はカウンタ0の値を読み込みます |
0x41 | Counter1 |
カウンタ1に値を設定するレジスタです 読み込み時はカウンタ1の値を読み込みます |
0x42 | Counter2 |
カウンタ2に値を設定するレジスタです 読み込み時はカウンタ2の値を読み込みます |
0x43 | Control Word |
制御コマンドを書き込むレジスタです 読み込みすることはできません(不定値)。 |
制御コマンド(Control Word)レジスタのフォーマット | ||
---|---|---|
ビット | シンボル | 説明 |
0 | BCD |
カウンタの値をバイナリとして扱うか、BCD(2進化10進数)として扱うか設定します 0:バイナリ 1:BCD |
1-3 | Mode |
モードを設定します 000b:モード0(タイマ) 001b:モード1(ワンショットタイマ) 010b:モード2(パルス生成モード) 011b:モード3(矩形波生成モード) 100b:モード4(ソフトウェアトリガモード) 101b:モード5(ハードウェアトリガモード) 110b:予約 111b:予約 |
4-5 | RL |
リード/ロードモードを設定します 00b:カウンタの値がカウンタレジスタにロードされます 01b:カウンタの値をLSB(Least Significant Byte)で書き込みます 10b:カウンタの値をMSB(Most Significant Byte)で書き込みます 11b:カウンタの値を最初の1バイトはLSBで、次の1バイトをMSBで書き込みます |
6-7 | SC |
カウンタを選択します 00b:カウンタ0 01b:カウンタ1 10b:カウンタ2 11b:無効 |
/* _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ Description : 8253 Programmable Interval Timer _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ */ /* Port Address */
#define PIT_REG_COUNTER0 0x0040 #define PIT_REG_COUNTER1 0x0041 #define PIT_REG_COUNTER2 0x0042 #define PIT_REG_CONTROL 0x0043
/* Input CLK0 */
#define DEF_PIT_CLOCK 1193181.67
/* ================================================================================= Description :initialization control word bit number value description 0 BCD Binary Coded Decimal 0:Binary 1:Binary Coded Decimal 1...3 Mode 000:timer 001:programmable one-shot 010:rate generator 011:square wave generator 100:software triggered strobe 101:hardware triggered strobe 110:undefined 111:undefined 4,5 RL Read/Load Mode 00:counter value is latched into an internal control register at the time of the i/o write operation 01:read or load least significant byte only 10:read or load most significatn byte only 11:read or load lsb first then msb 6,7 SC select counter 00:counter 0 01:counter 1 02:counter 2 11:ilegal value ================================================================================= */
#define DEF_PIT_COM_MASK_BINCOUNT 0x01 #define DEF_PIT_COM_MASK_MODE 0x0E #define DEF_PIT_COM_MASK_RL 0x30 #define DEF_PIT_COM_MASK_COUNTER 0xC0
/* binary count */
#define DEF_PIT_COM_BINCOUNT_BIN 0x00 #define DEF_PIT_COM_BINCOUNT_BCD 0x01
/* counter mode */
#define DEF_PIT_COM_MODE_TERMINAL 0x00 #define DEF_PIT_COM_MODE_PROGONE 0x02 #define DEF_PIT_COM_MODE_RATEGEN 0x04 #define DEF_PIT_COM_MODE_SQUAREWAVE 0x06 #define DEF_PIT_COM_MODE_SOFTTRIG 0x08 #define DEF_PIT_COM_MODE_HARDTRIG 0x0A
/* data transfer */
#define DEF_PIT_COM_RL_LATCH 0x00 #define DEF_PIT_COM_RL_LSBONLY 0x10 #define DEF_PIT_COM_RL_MSBONLY 0x20 #define DEF_PIT_COM_RL_DATA 0x30
/* counter */
#define DEF_PIT_COM_COUNTER0 0x00 #define DEF_PIT_COM_COUNTER1 0x40 #define DEF_PIT_COM_COUNTER2 0x80
/* _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ Funtion :setPitCounter Input :int freq < frequency Hz > unsigned char counter < type of counter > unsigned char mode < pit mode > Output :void Return :int < status > Description :set counter of a pic _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ */
int setPitCounter( int freq, unsigned char counter, unsigned char mode ) { unsigned short count; unsgined char command;
/* --------------------------------------------------------------------- */ /* calculate frequency */ /* --------------------------------------------------------------------- */
count = ( unsigned short )( DEF_PIT_CLOCK / freq );
/* --------------------------------------------------------------------- */ /* make initial command */ /* --------------------------------------------------------------------- */
command = mode | DEF_PIT_COM_RL_DATA | counter; outPortByte( PIT_REG_CONTROL, command );
/* --------------------------------------------------------------------- */ /* send counter value */ /* --------------------------------------------------------------------- */
outPortByte( PIT_REG_COUNTER0, ( unsigned char )( count & 0xFF ) ); outPortByte( PIT_REG_COUNTER0, ( unsigned char )( ( count >> 8 ) & 0xFF ) ); }
/* _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ Funtion :initPit Input :void Output :void Return :void Description :initialize pic _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
*/ void initPit( void ) {
/* --------------------------------------------------------------------- */ /* set counter0 100Hz */ /* --------------------------------------------------------------------- */
setPitCounter( 100, DEF_PIT_COM_COUNTER0, DEF_PIT_COM_MODE_SQUAREWAVE ); }
setPitCounter( 100, DEF_PIT_COM_COUNTER0, DEF_PIT_COM_MODE_SQUAREWAVE );
count = ( unsigned short )( DEF_PIT_CLOCK / freq );
command = mode | DEF_PIT_COM_RL_DATA | counter;
outPortByte( PIT_REG_CONTROL, command )
outPortByte( PIT_REG_COUNTER0, ( unsigned char )( count & 0xFF ) );
outPortByte( PIT_REG_COUNTER0, ( unsigned char )( ( count >> 8 ) & 0xFF ) );
割り込みハンドラ |
例外のエラーコード | ||
---|---|---|
ビット | シンボル | 説明 |
0 | EXT |
外部イベントフラグ 0:ソフトウェアにとって内部的なイベントによって例外が発生しています 1:ソフトウェアにとって外部的なイベント(IRQなど)によって例外が発生しています |
1 | IDT |
ディスクリプタ位置フラグ。参照するディスクリプタの場所を示すフラグです 0:エラーコードの”セグメントセレクタインデックス”はIDTのインデックスとなります 1:エラーコードの”セグメントセレクタインデックス”はGDTまたは現行のLDTのインデックスとなります |
2 | TI |
GDT/LDTフラグ。ビット1のIDTが0の場合のみ使用されます 0:エラーコードの”セグメントセレクタインデックス”はLDTのセグメントディスクリプタまたは ゲートディスクリプタのインデックスとなります 1:エラーコードの”セグメントセレクタインデックス”はGDTのインデックスとなります |
3-15 | Segment Selector Index |
セグメントセレクタインデックス エラーコードが参照するIDT、GDTまたは現在のLDTのインデックスとなります |
16-31 | Reserved | 予約領域です |
例外の割り込みベクタ | ||||
---|---|---|---|---|
ベクタ番号 | ニーモニック | 説明 | 原因 | エラーコード |
0 | #DE |
除算エラー Divided by 0 |
0で割り算を行った DIV命令、IDIV命令 |
無し |
1 | #DB |
シングルステップ(デバッグ) Single Step(Debug) |
デバッガによるコード、データの参照 | 無し |
2 | - |
マスク不可割り込み NMI(Non-Maskable Interrupt) |
マスク不可能な外部割り込み | 無し |
3 | #BP |
ブレークポイント(デバッグ) Break Point(Debug) |
INT 3命令 | 無し |
4 | #OF |
オーバフロー Overflow |
INTO命令 | 無し |
5 | #BR |
バウンド範囲外 Bounds Check |
BOUND命令 | 無し |
6 | #UD |
無効なオペコード(未定義なオペコード) Undifined Operation Code Instruction |
UD2命令または無効なオペコード | 無し |
7 | #NM |
デバイス使用不可能(数値演算コプロセッサ無し) No Coprocessor |
浮動小数点命令、WAIT/FWAIT命令 | 無し |
8 | #DF |
ダブルフォルト Double Fault |
例外、NMI、INTRを生成できる命令 | 常に0 |
9 | #MF |
コプセッサセグメントオーバーラン Coprocessor Segment Overrun |
浮動小数点命令 Intel386プロセッサ以降のプロセッサでは生成されません |
無し |
10 | #TS |
無効なTSS(Task State Segments) Invalid TSS |
タスクスイッチ、TSSアクセス | 例外を発生したセグメントディスクリプタのインデックス |
11 | #NP |
セグメントが不在 Segment Not Present |
セグメントレジスタのロード、システムセグメントへのアクセス | 例外を発生したセグメントディスクリプタのインデックス |
12 | #SS |
スタックセグメントフォルト Stack Segment Fault |
スタック操作、SSレジスタのロード | 例外を発生したセグメントセレクタ |
13 | #GP |
一般保護例外 General Protection Fault(GPF) |
メモリ参照、保護チェック |
セグメントディスクリプタへのロード中にフォルトが発生した場合 そのディスクリプタを指すセグメントセレクタ そうでない場合は0 |
14 | #PF |
ページフォルト Page Fault |
メモリ参照 |
・スタック上のエラーコード ・制御レジスタCR2の値 |
15 | - | 予約 | - | - |
16 | #MF |
浮動小数点エラー(数値演算フォルト) Coprocessor Error |
浮動小数点命令、WAIT/FWAIT命令 | 無し |
17 | #AC |
アライメントチェック Alignment Check |
メモリ参照 Intel486プロセッサ以降のプロセッサで発生します |
常に0 |
18 | #MC |
マシンチェック Machine Check |
エラーコード、ソースがモデルに依存 インテルPentinumプロセッサ以降 |
無し |
19 | #XF |
SIMD浮動小数点例外 SIMD FPU Exception |
SIMD浮動小数点命令 | 無し |
20-31 | - | 予約 | - | - |
32-255 | - |
マスク可能割り込み IRQやソフトウェア割り込みの割り込みベクタとして使用します |
INTRピンによる外部割り込みまたはINT命令 | 無し |
/* _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ Funtion :enter_interrupt Input :void Output :void Return :void Description :call for entering interrupt function _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ */
__inline__ void enter_interrupt( void ) { __asm__ __volatile__ ("pushad" ); }
/* _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ Funtion :interrupt_done Input :void Output :void Return :void Description :inform end of interrupt to pics _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ */
__inline__ void interrupt_done( void ) {
/* send end of interrupt(EOI) command to pic */
sendCommandPic( 0x20, 0x20 ); sendCommandPic( 0xA0, 0x20 ); }
/* _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ Funtion :exit_interrupt Input :void Output :void Return :void Description :call for exiting interrupt function _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ */
__inline__ void exit_interrupt( void ) { __asm__ __volatile__ (" popad" ); __asm__ __volatile__ (" iretd" ); }
static volatile int timer_tick; /* _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ Funtion :timer_interrupt Input :void Output :void Return :void Description :handling timer interrupt _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ */
void timer_interrupt( void ) {
/* --------------------------------------------------------------------- */ /* entering interrupt */ /* --------------------------------------------------------------------- */
enter_interrupt( );
/* --------------------------------------------------------------------- */ /* count tick */ /* --------------------------------------------------------------------- */
timer_tick++;
/* --------------------------------------------------------------------- */ /* inform end of interrupt to pics */ /* --------------------------------------------------------------------- */
interrupt_done( );
/* --------------------------------------------------------------------- */ /* exit interrupt */ /* --------------------------------------------------------------------- */
exit_interrupt( ); }