CPU実験室

誰も見向きもしない古いCPUをいじって動かしてみようというプロジェクトです

割込みをCで記述

アセンブラで正常動作していた割込み処理をCに移植しました

まず8259を初期化しますが8085モード4バイトインターバルで
割込みベクタのアドレスを9020H番地とします。
これはコードを9000H番地から配置するので+20Hとしてみました。
そのあと必要な割込み以外はマスクをかけます

/***************************************
	pit_init	8259初期化	
***************************************/
void pic_init(void)
{
  outp(PICD,0x37);
  outp(PICC,0x90);	/*interrupt vector table top address=0x9020	*/
  outp(PICC,0x00);
  outp(PICC,0xf7);	/*interrupt mask IR3=enable	*/
}

コードの先頭に来るスタートアップルーチンに細工が必要です。
ベクタテーブルは指定された絶対番地に配置しなければならないので
必ず先頭に置かれるstart:ラベルから+20Hしたところからベクタテーブル
(実際はjmp命令)が始まるようにorgで調整しています。
また飛び先は4バイトづつのインターバルを持つのでnopを1個挿入してます

start_:
  CALL 	main_
  RST	7
	
  org $+1ch

  jmp	intr0_
  nop
  jmp	intr1_
  nop
  jmp	intr2_
  nop
  jmp	intr3_
  nop
  jmp	intr4_
  nop
  jmp	intr5_
  nop
  jmp	intr6_
  nop
  jmp	intr7_
	
  END

実際の割込みハンドラです。ここでは8253から10Hzの割込みが発生するたびに
clk_event()を実行させる例です
レジスタのPUSH/POPはインライン文で書くしかありません

void intr3(void)	/*  8253 TIMER1(10Hz)	*/
{
  _asm_c("\n\tPUSH PSW\n\tPUSH H\n\tPUSH B\n\tPUSH D\n");
  clk_event();   /* 割込み処理本体  */
  eoi();      /* 8259へEOIを発行 */
  _asm_c("\n\tPOP D\n\tPOP B\n\tPOP H\n\tPOP PSW\n");
}