;* 
;*  TOPPERS/SSP Kernel
;*      Smallest Set Profile Kernel
;*
;*  Copyright (C) 2010,2011 by Naoki Saito
;*             Nagoya Municipal Industrial Research Institute, JAPAN
;* 
;*  上記著作権者は，以下の (1)〜(4) の条件を満たす場合に限り，本ソフトウェ
;*  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改変・
;*  再配布（以下，利用と呼ぶ）することを無償で許諾する．
;*  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作権
;*      表示，この利用条件および下記の無保証規定が，そのままの形でソース
;*      コード中に含まれていること．
;*  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使用
;*      できる形で再配布する場合には，再配布に伴うドキュメント（利用者マ
;*      ニュアルなど）に，上記の著作権表示，この利用条件および下記の無保
;*      証規定を掲載すること．
;*  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使用
;*      できない形で再配布する場合には，次のいずれかの条件を満たすこと．
;*    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著作
;*        権表示，この利用条件および下記の無保証規定を掲載すること．
;*    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに報
;*        告すること．
;*  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損害
;*      からも，上記著作権者およびTOPPERSプロジェクトを免責すること．また，
;*      本ソフトウェアのユーザまたはエンドユーザからのいかなる理由に基づ
;*      く請求からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
;* 
;*  本ソフトウェアは，無保証で提供されているものである．上記著作権者およ
;*  びTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的に対す
;*  る適合性も含めて，いかなる保証も行わない．また，本ソフトウェアの利用
;*  により直接的または間接的に生じたいかなる損害に関しても，その責任を負
;*  わない．
;* 

;
;	プロセッサ依存モジュール アセンブリ言語部（M16Cファミリ共通部分）
;
	.section	program, code, align

	; 外部で定義されているシンボル
	.glb    __kernel_intnest
	.glb    __kernel_reqflg
	.glb    __kernel_disdsp
	.glb	__kernel_interrupt_dispatch
	
	; 外部へ公開するシンボル
	.glb    	__kernel_interrupt_entry

	.include	target_support.inc

;
; 割込み/CPU例外の出入口処理(共通部)
;   前提条件
;	・FLGレジスタのIビット=0, IPLは受付けた割込みのIPL.
;	・ハンドラのアドレスが a0a1 (M32Cの場合, a0) に格納されている.
;   ・CPU例外ハンドラの入口から来た場合，スタックポインタの
;     先頭番地(p_excinf)がレジスタ r1 (M32Cの場合，r3r1)に格納されており，
;     これはCPU例外ハンドラの引数としてそのまま渡される．
;
;	レジスタがスタック上にどのように保存されているかを以下に示す.
;	図は並び順のみを表現したものであり，サイズを考慮していないことに注意する．
;	正確にはデータシートを参照のこと．
;	この図では上が低位, 下が高位のアドレスで, スタックは図の下側から
;	上方向に向かって積み上げられるものとする.
;
;  【 M32Cの場合】           	【M16Cの場合】
;
;	-------------<-- p_excinf	------------- <-- p_excinf
;	| R0(2byte) |            	| R0(2byte) |
;	-------------            	-------------
;	| R1(2byte) |            	| R1(2byte) |
;	-------------            	-------------
;	| R2(2byte) |            	| R2(2byte) |
;	-------------            	-------------
;	| R3(2byte) |            	| R3(2byte) |
;	-------------            	-------------
;	| A0(4byte) |            	| A0(2byte) |
;	-------------            	-------------
;	| A1(4byte) |            	| A1(2byte) |
;	-------------            	-------------
;	| SB(4byte) |            	| SB(2byte) |
;	-------------            	-------------
;	| FB(4byte) |            	| FB(2byte) |
;	-------------            	-------------
;	| PC(4byte) |            	|PC下(2byte)|
;	-------------            	-------------
;	| FLG(2byte)|            	|FLG下(1byte)|
;	-------------            	--------------
;	                         	|FLG上(4bit) |
;	                            |/PC上(4bit) |
;	                         	--------------
;
;	ハンドラからリターンした後は, 多重割込みでなく, かつ，
;	reqflg が TRUE，かつ，disdsp が FALSE の時に，interrupt_dispatch へ分岐する．
;
;	多重割込みかどうかは割込みネストカウンタの値で判定する.
;	intnest > 0 ならば多重割込みであると判定する.
;
__kernel_interrupt_entry:
	inc.b	__kernel_intnest   	; ネストカウンタをインクリメント
	fset 	i                  	; 割込み許可(IPLは受け付けられた割込みのレベル)
	__call_int_handler         	; 割込みハンドラ呼び出し(XXX_support.inc)
	fclr	i                  	; CPUロック状態へ
	dec.b	__kernel_intnest   	; ネストカウンタをデクリメント
	jnz  	int_return         	; 戻り先が非タスクコンテキスト(非ゼロ)なら単にリターン
	mov.w	__kernel_reqflg, r1	; ディスパッチ要求があるかどうか
	jz   	int_return         	; なければ，単にリターン
	mov.w	#0, __kernel_reqflg	; reqflg = FALSE に戻しておく
	mov.w	__kernel_disdsp, r0	; ディスパッチ禁止かどうか
	jnz  	int_return         	; 禁止なら，単にリターン
	jsr  	__kernel_interrupt_dispatch	; 新たにタスクを起動する
int_return:
	popm	r0,r1,r2,r3,a0,a1,sb,fb	; レジスタ復帰
	reit

	; 未使用割込みの処理
	.glb _unused_interrupt
_unused_interrupt:
	reit

	.end
	