www.pudn.com > norti2.0 > NOCIF.ASM
;******************************************************************************
;* NORTi/86 CPUインターフェースモジュール(MASM,TASM互換形式) *
;* *
;* File name : nocif.asm *
;* Copyright (c) Miyazaki System Planning Office. 1991-1995 *
;* *
;* Assemble : masm /MX nocif.asm; (for MS-C 5.1/6.0) *
;* masm /MX /DC7 nocif.asm; (for MS-C 7.0) *
;* tasm /MX /DTC nocif.asm (for TC, TC++, BC++) *
;* *
;* /DCPU=286 で PUSHA/POPA 命令が使われます。 *
;* /DROM で ROM 化用の sysini_rom のみがアセンブルされます。 *
;* /DPIC で 割込みコントローラ対応部分もアセンブルされます。 *
;* /DMON=xxH で モニタ信号出力部分もアセンブルされます。 *
;* *
;* 91-10-25 TRCOM Version *
;* 92-02-16 Ver1.00 *
;* 92-08-20 Ver1.10 *
;* 93-01-18 Ver1.11 *
;* 93-02-17 Ver1.12 *
;* 93-05-16 Ver1.13β *
;* 94-01-05 Ver1.14 *
;* 95-06-15 Ver1.20 *
;* 95-09-12 Ver1.21 *
;******************************************************************************
; タスク/割込みモニタ信号とは
;
; 任意のポートへ下記の信号を出力します。
; タスク切り替えや割込み禁止許可のタイミングを、ロジアナ等で解析できます。
;
; 信号の構成
;
; bit0 ホ「 実行タスクIDの下位4ビット(0〜F)
; bit1 ニ
; bit2 ニ
; bit3 コ
; bit4 ホ「 割込みネストレベルの下位2ビット(0〜3)
; bit5 コ
; bit6 「「 割込み禁止(1)/許可(0)状態
; bit7 「「 ユーザ解放(out_usrsig 関数)
;
; 信号の出力方法
;
; 信号を出力させるポートアドレスを MON に定義して nocif.asm をアセンブルし、
; nocif.obj を他のモジュールと共にリンクしてください。
;
; (例) masm /MX /DMON=40H nocif.asm
; cl ・・・・ nocif.obj nolib.lib /link /NOE
;* プロセッサの型
ifdef CPU
if (CPU GE 186)
.186
endif
endif
;* ライブラリ生成用分割アセンブルスイッチ
ifdef ROM
SSW EQU -1 ; sysini_rom のみアセンブル
else
ifndef SW
SSW EQU 0 ; 全てアセンブル
else
if (SW EQ 1)
SSW EQU 1 ; 分割アセンブル
endif
if (SW EQ 2)
SSW EQU 2
endif
if (SW EQ 3)
SSW EQU 3
endif
if (SW EQ 4)
SSW EQU 4
endif
endif
endif
;* 構造体メンバーの位置
TCB_SP EQU 36 ; TCB の退避スタックポインタの位置 (注)
TCB_TID EQU 12 ; TCB のタスクIDの位置
CTX_STKHQQ EQU 0 ; 退避コンテキスト内の STKHQQ の位置
CTX_AX EQU 20 ; 退避コンテキスト内の AX の位置
CTX_CS EQU 28 ; 退避コンテキスト内の CS の位置
; (注) TCB の構造を変更した場合は、TCB_XX の値を必ず見直してください。
;* 外部参照(NOKNL.C)
EXTRN C_SYSINI:NEAR ; システム初期化
EXTRN WUP_TSK:FAR
EXTRN SCHEDULE:NEAR ; スケジューラ
EXTRN _RDQ:WORD ; レディキューヘッダ
EXTRN _IMASK:WORD ; 割込みマスクフラグ
EXTRN _INEST:BYTE ; 割込みネストカウンタ(減カウント)
EXTRN _DELAY:BYTE ; 遅延ディスパッチ要求フラグ
EXTRN _ISP:WORD ; 割込みスタックポインタ初期値
;* 外部参照(ユーザ定義)
EXTRN _intini:FAR ; 割込み初期化
ifdef PIC
EXTRN VDIS_PIC:FAR ; 割込みコントローラ割込みマスク
EXTRN VENA_PIC:FAR ; 割込みコントローラ割込みマスク解除
endif
;* TURBO-Cのスタック領域管理変数
ifdef TC
EXTRN __stklen:WORD ; スタック長
if ((SSW NE 0) AND (SSW NE 1))
EXTRN STKHQQ:WORD ; MS-Cと合わせる
endif
else
;* MS-Cのスタック領域管理変数
ifdef C7
EXTRN _STKHQQ:WORD ; スタック先頭ポインタ(MS-C 7.0)
STKHQQ EQU _STKHQQ
else
EXTRN STKHQQ:WORD ; スタック先頭ポインタ(MS-C 5.1/6.0)
endif
endif
;* デバッグ用
ifdef MON
if ((SSW NE 0) AND (SSW NE 1))
EXTRN _MONSIG:BYTE ; モニタ信号出力バッファ
endif
endif
;* セグメントの定義と内部変数の定義
_BSS SEGMENT WORD PUBLIC 'BSS'
DGROUP GROUP _BSS
ASSUME DS:DGROUP
if ((SSW EQ 0) OR (SSW EQ 1))
PUBLIC _TOPCS
_TOPCS DW ? ; ユーザコード先頭セグメント
ifdef TC ; TURBO-C では
PUBLIC STKHQQ
STKHQQ DW ? ; MS-Cと合わせるためSTKHQQをダミー定義
endif
ifdef MON
PUBLIC _MONSIG
_MONSIG DB ? ; モニタ信号出力バッファ
endif
endif
if (SSW EQ 3)
EXTRN _TOPCS:WORD
endif
_BSS ENDS
_TEXT SEGMENT WORD PUBLIC 'CODE'
ASSUME CS:_TEXT
if ((SSW EQ 0) OR (SSW EQ 1))
;************************************************
;* バージョンの定義 *
;************************************************
DB 'NORTi/86 (c) MiSPO'
PUBLIC _NORTI_VER
_NORTI_VER: ; T_VER NORTI_VER;
DW 0108H ; メーカー番号(宮崎システム設計事務所)
ifdef TC
DW 0002H ; 形式番号(NORTi/86 for TURBO-C)
else
DW 0001H ; 形式番号(NORTi/86 for MS-C)
endif
DW 5201H ; 仕様書バージョン(μITRON仕様書Ver2.01)
DW 0121H ; 製品バージョン(Ver1.21)
DW 0000H ; 製品管理情報0
DW 0000H ; 製品管理情報1
DW 0000H ; 製品管理情報2
DW 0000H ; 製品管理情報3
if (@Cpu AND 2)
DW 0062H ; CPU情報(80286)
else
DW 0060H ; CPU情報(8086)
endif
DW 8000H ; バリエーション記述(レベルS)
;******************************************************************************
;* *
;* システムコール関数 *
;* *
;******************************************************************************
ifdef TC
;************************************************
;* システム初期化(TURBO-C) *
;************************************************
PUBLIC SYSINI
SYSINI: ; void far pascal sysini(void)
CLI ; CPU割込み禁止
MOV [_TOPCS],CS ; TOPCS = ここ(_TEXT)のCS;
MOV AX,SS
CMP AX,DGROUP ; SS == DGROUP (スモール/ミディアム) ?
MOV AX,0 ; No : STKHQQ = 0;
JNZ SYSINI_COM
SUB AX,[__stklen] ; Yes : STKHQQ = 0 - _stklen;
else
;************************************************
;* システム初期化(MS-C) *
;************************************************
PUBLIC SYSINI
SYSINI: ; void far pascal sysini(void)
CLI ; CPU 割込み禁止
MOV CX,BP
MOV BP,SP
MOV AX,[BP+2]
MOV BP,CX
MOV [_TOPCS],AX ; TOPCS = 呼出し元(main関数)のCS;
JMP sysini_4
endif
;************************************************
;* システム初期化(MS-C/TURBO-C/ROM化共通部分) *
;************************************************
PUBLIC SYSINI_COM
SYSINI_COM:
MOV [STKHQQ],AX
sysini_4:
PUSH [STKHQQ]
PUSHF
POP AX
OR AH,02H
PUSH AX ; タスク起動時のFLAGS(IF=1)
SUB SP,12*2 ; (CS,IP,アキ,アキ,AX,CX,DX,BX,SP,BP,SI,DI)
PUSH DS ; タスク起動時のDS
PUSH DS ; (ES)
SUB SP,2 ; (STKHQQ)
CALL C_SYSINI ; c_sysini(STKHQQ, ctx);
CALL FAR PTR _intini ; intini(); 割込み初期化
ifdef MON ; モニタ信号出力
MOV AL,40H ; c = 0x40;
OUT MON,AL ; outp(MON, c);
MOV _MONSIG,AL ; MONSIG = c;
endif
RETF
endif ;((SSW EQ 0) OR (SSW EQ 1))
if ((SSW EQ 0) OR (SSW EQ 2))
;************************************************
;* 割込みハンドラの開始 *
;************************************************
; T_CTX 構造体
; !______! + 0!STKHQQ!<- TCBの退避SP
; !______! + 2!__ES__!
; !______! + 4!__DS__!
; !______! + 6!__DI__!
; !______! + 8!__SI__!
; !______! +10!__BP__!
; !______! +12!_(SP)_!
; !______! コンテキスト退避 +14!__BX__!
; !______! -----> +16!__DX__!
; !______! +18!__CX__!
; !______! +20!__AX__!
; !__IP'_!<- 本関数入口でのSP +22!__アキ__!
; !__CS'_! +24!__アキ__!
; !__IP__!-・ +26!__IP__!
; !__CS__! | 割込みによる退避 +28!__CS__!
; !_FLAGS!-・ +30!_FLAGS!
PUBLIC ENT_INT
ENT_INT: ; void far pascal ent_int(void)
if (@Cpu AND 2)
PUSHA ; 80186 以上なら PUSHA 命令で
else
PUSH AX ; AX 退避
PUSH CX ; CX 退避
PUSH DX ; DX 退避
PUSH BX ; BX 退避
SUB SP,2
PUSH BP ; BP 退避
PUSH SI ; SI 退避
PUSH DI ; DI 退避
endif
PUSH DS ; DS 退避
MOV AX,DGROUP
MOV DS,AX ; DS 設定
ifdef MON ; モニタ信号出力
MOV AL,_MONSIG ; c = MONSIG;
MOV AH,AL ; c = (c & ~0x70)
ADD AH,10H ; | ((c + 0x10) & 0x30) | 0x40;
AND AX,308FH ; bit5-4 = 割込みネストレベル
OR AH,40H ; bit6 = 割込み禁止(1)
OR AL,AH
OUT MON,AL ; outp(MON, c);
MOV _MONSIG,AL ; MONSIG = c;
endif
CLD
PUSH ES ; ES 退避
PUSH [STKHQQ] ; STKHQQ 退避
MOV BP,SP
MOV SI,[BP+CTX_AX+2] ; リターンアドレス(IP')を得る
MOV DI,[BP+CTX_AX+4] ; リターンアドレス(CS')を得る
SUB [_INEST],1 ; if (--INEST == -1)
JNC ent_int_8 ; {
MOV BX,[_RDQ]
MOV [BX+TCB_SP+2],SS ; RDQ[0].head->sp = SS:SP;
MOV [BX+TCB_SP],SP
MOV SS,[_ISP+2] ; SS:SP = ISP;
MOV SP,[_ISP]
ent_int_8: ; }
PUSH DI ; リターンアドレス(CS')をPUSH
PUSH SI ; リターンアドレス(IP')をPUSH
RETF ; return;
endif ;((SSW EQ 0) OR (SSW EQ 2))
if ((SSW EQ 0) OR (SSW EQ 3))
;************************************************
;* 割込みハンドラの開始(CodeViewデバッグ用) *
;************************************************
PUBLIC ENT_INT2
ENT_INT2: ; int far pascal ent_int2(void)
if (@Cpu AND 2)
PUSHA ; 80186 以上なら PUSHA 命令で
else
PUSH AX ; AX 退避
PUSH CX ; CX 退避
PUSH DX ; DX 退避
PUSH BX ; BX 退避
SUB SP,2
PUSH BP ; BP 退避
PUSH SI ; SI 退避
PUSH DI ; DI 退避
endif
PUSH DS ; DS 退避
MOV AX,DGROUP
MOV DS,AX ; DS 設定
ifdef MON ; モニタ信号出力
MOV AL,_MONSIG ; c = MONSIG;
MOV AH,AL ; c = (c & ~0x70)
ADD AH,10H ; | ((c + 0x10) & 0x30) | 0x40;
AND AX,308FH ; bit5-4 = 割込みネストレベル
OR AH,40H ; bit6 = 割込み禁止(1)
OR AL,AH
OUT MON,AL ; outp(MON, c);
MOV _MONSIG,AL ; MONSIG = c;
endif
CLD
PUSH ES ; ES 退避
PUSH [STKHQQ] ; STKHQQ 退避
MOV BP,SP
MOV SI,[BP+CTX_AX+2] ; リターンアドレス(IP')を得る
MOV DI,[BP+CTX_AX+4] ; リターンアドレス(CS')を得る
MOV AX,[BP+CTX_CS] ; AX = 割込み時のCS
SUB [_INEST],1 ; if (--INEST == -1)
JNC ent_int_6 ; {
MOV BX,[_RDQ]
MOV [BX+TCB_SP+2],SS ; RDQ[0].head->sp = SS:SP;
MOV [BX+TCB_SP],SP
MOV SS,[_ISP+2] ; SS:SP = ISP;
MOV SP,[_ISP]
ent_int_6: ; }
CMP AX,[_TOPCS] ; 割込み時のCS値判断
JB ent_int_7
CMP AX,DGROUP
JA ent_int_7 ; if (TOPCS <= AX && AX <= DGROUP)
XOR AX,AX ; AX = 0; ユーザコード内
ent_int_7:
PUSH DI ; リターンアドレス(CS')をPUSH
PUSH SI ; リターンアドレス(IP')をPUSH
RETF ; return AX;
endif ;((SSW EQ 0) OR (SSW EQ 3))
if ((SSW EQ 0) OR (SSW EQ 1))
;************************************************
;* 割込みハンドラから復帰する *
;************************************************
PUBLIC RET_INT
RET_INT: ; void far pascal ret_int(void)
ADD SP,2*2 ; リターンアドレス破棄
ret_int_2:
CLI ; CPU割込み禁止
ifdef MON ; モニタ信号出力
MOV AL,_MONSIG ; c = MONSIG;
OR AL,40H ; c |= 0x40; 割込み禁止
OUT MON,AL ; outp(MON, c);
MOV _MONSIG,AL ; MONSIG = c;
endif
ifdef PIC
CALL FAR PTR VDIS_PIC ; PIC割込みマスク
ifdef MON ; モニタ信号出力
MOV AL,_MONSIG ; c = MONSIG;
AND AL,0BFH ; c &= ~0x40; 割込み許可
OUT MON,AL ; outp(MON, c);
MOV _MONSIG,AL ; MONSIG = c;
endif
STI ; CPU割込み許可
endif
INC [_INEST] ; if (++INEST == 0)
JNZ ret_int_4 ; {
SHR [_DELAY],1 ; if (DELAY != 0)
JNC ret_int_3 ; {
CALL SCHEDULE ; schedule();
ret_int_3: ; }
MOV BX,[_RDQ]
ifdef MON ; モニタ信号出力
MOV AL,_MONSIG ; c = MONSIG;
AND AL,0F0H ; c = (c & 0xf0)
MOV AH,[BX+TCB_TID] ; | (RDQ[0].tid & 0x0f);
AND AH,0FH ; bit3-0 = タスクID
OR AL,AH
OUT MON,AL ; outp(MON, c);
MOV _MONSIG,AL ; MONSIG = c;
endif
MOV SS,[BX+TCB_SP+2] ; SS:SP = RDQ[0].head->sp
MOV SP,[BX+TCB_SP]
ret_int_4: ; }
POP [STKHQQ] ; STKHQQ 復元
ifdef PIC
CLI ; CPU割込み禁止
ifdef MON ; モニタ信号出力
MOV AL,_MONSIG ; c = MONSIG;
OR AL,40H ; c |= 0x40; 割込み禁止
OUT MON,AL ; outp(MON, c);
MOV _MONSIG,AL ; MONSIG = c;
endif
CALL FAR PTR VENA_PIC ; PIC割込みマスク解除
endif
POP ES ; ES 復元
ifdef MON ; モニタ信号出力
MOV AL,_MONSIG ; c = MONSIG;
MOV AH,AL ; c = (c & ~0x70)
SUB AH,10H ; | ((c - 0x10) & 0x30);
AND AX,308FH ; bit6 = 割込み許可(0)
OR AL,AH ; bit4,5 = 割込みネストレベル
OUT MON,AL ; outp(MON, c);
MOV _MONSIG,AL ; MONSIG = c;
endif
POP DS ; DS 復元
if (@Cpu AND 2)
POPA ; 80186 以上なら POPA 命令で
else
POP DI ; DI 復元
POP SI ; SI 復元
POP BP ; BP 復元
ADD SP,2
POP BX ; BX 復元
POP DX ; DX 復元
POP CX ; CX 復元
POP AX ; AX 復元
endif
ADD SP,2*2 ; アキ
IRET ; IP,CS,FLAGS 復元
;************************************************
;* 割込み処理復帰とタスク起床を行う *
;************************************************
PUBLIC RET_WUP
RET_WUP: ; void far pascal ret_wup(ID tskid)
ADD SP,2*2 ; リターンアドレス破棄
PUSH CS
CALL NEAR PTR WUP_TSK ; wup_tsk(tskid);
JMP ret_int_2 ; --> 以下 ret_int() と同じ
endif ;((SSW EQ 0) OR (SSW EQ 1))
if ((SSW EQ 0) OR (SSW EQ 1))
;******************************************************************************
;* *
;* カーネル内部関数 *
;* *
;******************************************************************************
;************************************************
;* コンテキスト切替え *
;************************************************
; T_CTX 構造体
; !______! + 0!STKHQQ!<- TCBの退避SP
; !______! + 2!__ES__!
; !______! + 4!__DS__!
; !______! + 6!__DI__!
; !______! + 8!__SI__!
; !______! +10!__BP__!
; !______! +12!_(SP)_!
; !______! コンテキスト退避 +14!_(BX)_!
; !______! -----> +16!_(DX)_!
; !______! +18!_(CX)_!
; !______! +20!__AX__! AX = E_OK
; !______! +22!__アキ__!
; !______! +24!__アキ__!
; !______! +26!__IP__!
; !______! +28!__CS__!
; !__IP__!<- 本関数入口でのSP +30!_FLAGS! IF = 1
; C言語から呼ばれるので BX,CX,DX は退避不要.
; ES も退避不要だが、プロテクトモードで POP する際の一般保護例外回避のため退避
; +12位置の SP は PUSHA/POPA 命令との互換用.
PUBLIC CTXSWITCH
CTXSWITCH: ; ER near pascal ctxswitch(void)
; コンテキスト退避
POP CX ; (POP IP)
PUSHF
POP AX
OR AH,02H
PUSH AX ; 割込み許可(IF=1)の FLAGS 退避
PUSH CS ; CS 退避
PUSH CX ; IP 退避
SUB SP,2*2 ; アキ
XOR AX,AX ; AX の退避値は E_OK(0);
if (@Cpu AND 2)
PUSHA ; 80186 以上なら PUSHA 命令で
else
PUSH AX
SUB SP,4*2 ; CX,DX,BX,SP は退避不要
PUSH BP ; BP 退避
PUSH SI ; SI 退避
PUSH DI ; DI 退避
endif
PUSH DS ; DS 退避
PUSH ES ; ES 退避
PUSH [STKHQQ] ; STKHQQ 退避
MOV BX,[_RDQ]
MOV [BX+TCB_SP+2],SS ; RDQ[0].head->sp = SS:SP;
MOV [BX+TCB_SP],SP
; 実行タスク選択
CALL SCHEDULE ; schedule();
; コンテキスト復元
MOV BX,[_RDQ]
ifdef MON ; タスクモニタ信号出力
MOV AL,_MONSIG ; c = MONSIG;
AND AL,0F0H ; c = (c & 0xf0)
MOV AH,[BX+TCB_TID] ; | (RDQ[0].tid & 0x0f);
AND AH,0FH
OR AL,AH
OUT MON,AL ; outp(MON, c);
MOV _MONSIG,AL ; MONSIG = c;
endif
MOV SS,[BX+TCB_SP+2] ; SS:SP = RDQ[0].head->sp
MOV SP,[BX+TCB_SP]
POP [STKHQQ] ; STKHQQ 復元
ifdef PIC
CLI ; 割込み禁止
ifdef MON ; モニタ信号出力
MOV AL,_MONSIG ; c = MONSIG;
OR AL,40H ; c |= 0x40; 割込み禁止
OUT MON,AL ; outp(MON, c);
MOV _MONSIG,AL ; MONSIG = c;
endif
CALL FAR PTR VENA_PIC ; PIC割込みマスク解除
endif
POP ES ; ES 復元
ifdef MON ; モニタ信号出力
MOV AL,_MONSIG ; c = MONSIG;
AND AL,0BFH ; c &= ~0x40; 割込み許可
OUT MON,AL ; outp(MON, c);
MOV _MONSIG,AL ; MONSIG = c;
endif
POP DS ; DS 復元
if (@Cpu AND 2)
POPA ; 80186 以上なら POPA 命令で
else
POP DI ; DI 復元
POP SI ; SI 復元
POP BP ; BP 復元
ADD SP,2
POP BX ; BX 復元
POP DX ; DX 復元
POP CX ; CX 復元
POP AX ; AX 復元
endif
ADD SP,2*2 ; アキ
IRET ; IP,CS,FLAGS 復元
;************************************************
;* タスク起動時のコンテキスト初期化 *
;************************************************
PUBLIC INIT_CTX
INIT_CTX: ; void near pascal init_ctx(T_CTX far *ctx)
RET 4
;************************************************
;* システムコール入口での割込みマスク *
;************************************************
PUBLIC SET_IMASK
SET_IMASK: ; void near pascal set_imask(void)
PUSHF
POP AX
NOT AX
AND AX,0200H
CLI ; CPU割込み禁止
MOV [_IMASK],AX ; IMASK = ~(割込み禁止前のIF);
ifdef MON ; モニタ信号出力
MOV AL,_MONSIG ; c = MONSIG;
OR AL,40H ; c |= 0x40; 割込み禁止
OUT MON,AL ; outp(MON, c);
MOV _MONSIG,AL ; MONSIG = c;
endif
ifdef PIC
CALL FAR PTR VDIS_PIC ; PIC割込みマスク
CMP [_IMASK],0 ; if (IMASK == 0)
JNZ set_imask_4 ; {
ifdef MON ; モニタ信号出力
MOV AL,_MONSIG ; c = MONSIG;
AND AL,0BFH ; c &= ~0x40; 割込み許可
OUT MON,AL ; outp(MON, c);
MOV _MONSIG,AL ; MONSIG = c;
endif
STI ; CPU割込み許可
set_imask_4: ; }
endif
RET
;************************************************
;* システムコール出口での割込みマスク復元 *
;************************************************
PUBLIC RET_IMASK
RET_IMASK: ; ER near pascal ret_imask(void)
ifdef PIC
CLI
ifdef MON ; モニタ信号出力
MOV AL,_MONSIG ; c = MONSIG;
OR AL,40H ; c |= 0x40; 割込み禁止
OUT MON,AL ; outp(MON, c);
MOV _MONSIG,AL ; MONSIG = c;
endif
CALL FAR PTR VENA_PIC ; PIC割込みマスク解除
endif
CMP [_IMASK],0 ; if (IMASK == 0)
JNZ ret_imask_4 ; {
ifdef MON ; モニタ信号出力
MOV AL,_MONSIG ; c = MONSIG;
AND AL,0BFH ; c &= ~0x40; 割込み許可
OUT MON,AL ; outp(MON, c);
MOV _MONSIG,AL ; MONSIG = c;
endif
STI ; CPU割込み許可
ret_imask_4: ; }
XOR AX,AX ; return E_OK;
RET
;************************************************
;* タイマ処理中の割込みマスク一時解除 *
;************************************************
PUBLIC OPE_IMASK
OPE_IMASK: ; void near pascal ope_imask(void)
CMP [_IMASK],0 ; if (IMASK != 0)
JNZ ope_imask_4 ; return;
ifdef PIC
CLI ; CPU割込み禁止
ifdef MON ; モニタ信号出力
MOV AL,_MONSIG ; c = MONSIG;
OR AL,40H ; c |= 0x40; 割込み禁止
OUT MON,AL ; outp(MON, c);
MOV _MONSIG,AL ; MONSIG = c;
endif
CALL FAR PTR VENA_PIC ; PIC割込みマスク解除
endif
ifdef MON ; モニタ信号出力
MOV AL,_MONSIG ; c = MONSIG;
AND AL,0BFH ; c &= ~0x40; 割込み許可
OUT MON,AL ; outp(MON, c);
MOV _MONSIG,AL ; MONSIG = c;
endif
STI ; CPU割込み許可
NOP ; 他の割込みを入れる
CLI ; CPU割込み禁止
MOV [_IMASK],0 ; IMASK = 0;
ifdef MON ; モニタ信号出力
MOV AL,_MONSIG ; c = MONSIG;
OR AL,40H ; c |= 0x40; 割込み禁止
OUT MON,AL ; outp(MON, c);
MOV _MONSIG,AL ; MONSIG = c;
endif
ifdef PIC
CALL FAR PTR VDIS_PIC ; PIC割込みマスク
ifdef MON ; モニタ信号出力
MOV AL,_MONSIG ; c = MONSIG;
AND AL,0BFH ; c &= ~0x40; 割込み許可
OUT MON,AL ; outp(MON, c);
MOV _MONSIG,AL ; MONSIG = c;
endif
STI ; CPU割込み許可
endif
ope_imask_4:
RET
endif ;((SSW EQ 0) OR (SSW EQ 1))
;******************************************************************************
;* *
;* 独自システムコール関数 *
;* *
;******************************************************************************
if ((SSW EQ 0) OR (SSW EQ 4))
;************************************************
;* CPUフラグレジスタのIFクリア(割込み禁止) *
;************************************************
PUBLIC VDIS_PSW
VDIS_PSW: ; UINT far pascal vdis_psw(void)
PUSHF
POP AX ; 戻値は割込み禁止前のFLAGS
CLI ; CPU割込み禁止
ifdef MON ; モニタ信号出力
MOV BX,AX
MOV AL,_MONSIG ; c = MONSIG;
OR AL,40H ; c |= 0x40; 割込み禁止
OUT MON,AL ; outp(MON, c);
MOV _MONSIG,AL ; MONSIG = c;
MOV AX,BX
endif
RETF
endif ;((SSW EQ 0) OR (SSW EQ 4))
if ((SSW EQ 0) OR (SSW EQ 4))
;************************************************
;* CPUフラグレジスタ設定 *
;************************************************
PUBLIC VSET_PSW
VSET_PSW: ; void far pascal vset_psw(UINT psw)
POP CX
POP BX
ifdef MON ; モニタ信号出力
POP AX
PUSH AX
CLI
MOV AL,_MONSIG ; c = MONSIG;
AND AL,0BFH ; c &= ~0x40; 割込み許可
AND AH,02H
JNZ vset_psw_2 ; if (!(psw & IF))
OR AL,40H ; c |= 0x40; 割込み禁止
vset_psw_2:
OUT MON,AL ; outp(MON, c);
MOV _MONSIG,AL ; MONSIG = c;
endif
POPF ; FLAGS = psw;
PUSH BX
PUSH CX
RETF
endif ;((SSW EQ 0) OR (SSW EQ 4))
if ((SSW EQ 0) OR (SSW EQ 1))
;************************************************
;* ユーザ用モニタ信号出力 *
;************************************************
PUBLIC OUT_USRSIG
OUT_USRSIG: ; void far pascal out_usrsig(BOOL on)
ifdef MON
MOV CX,BP
MOV BP,SP
PUSHF
CLI
MOV AL,_MONSIG ; c = MONSIG;
AND AL,7FH ; c &= ~0x80;
CMP WORD PTR [BP+4],0
JZ out_usrsig_2 ; if (on)
OR AL,80H ; c |= 0x80;
out_usrsig_2:
OUT MON,AL ; outp(MON, c);
MOV _MONSIG,AL ; MONSIG = c;
POPF
MOV BP,CX
endif
RETF 2
endif ;((SSW EQ 0) OR (SSW EQ 1))
_TEXT ENDS
ifdef ROM
;******************************************************************************
;* *
;* ROM化用 *
;* *
;******************************************************************************
EXTRN SYSINI_COM:NEAR
;* TURBO-C ROM化でのスタックセグメント
ifdef TC
_STACK SEGMENT PARA STACK 'STACK'
_STACK ENDS
DGROUP GROUP _STACK
else
;* MS-C ROM化でのスタックセグメント
STACK SEGMENT PARA STACK 'STACK'
STACK ENDS
endif
; ROM化では、sysini_rom() で現在の SP 値から上記スタックセグメントの先頭まで、
; タスクのスタックを確保できると判断しています。
; TURBO-C ラージ/コンパクトの ROM 化では、標準の sysini を使います。
_TEXT SEGMENT
;************************************************
;* システム初期化(ROM化) *
;************************************************
PUBLIC SYSINI_ROM
SYSINI_ROM: ; void far pascal sysini_rom(void)
CLI ; CPU 割込み禁止
MOV AX,SS
CMP AX,DGROUP ; SS == DGROUP ?
MOV AX,0 ; No : STKHQQ = 0;
JNZ sysini_3
ifdef TC
MOV AX,_STACK
else
MOV AX,STACK
endif
SUB AX,DGROUP ; (注)
MOV CL,4 ;
SHL AX,CL ; Yes : STKHQQ = offset DGROUP:_STACK
sysini_3:
JMP SYSINI_COM
; (注) TASM では、MOV AX,offset DGROUP:_STACK を行えないので実行時に計算
_TEXT ENDS
endif ;ROM
END