Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

211 lines
7.4 KiB

;#########################################################################
;## DELAY ルーチン ##
;##  指定された時間だけ待つルーチン(単位ms) ##
;## ##
;## 基準となるCPUクロック ##
;## V30:10MHZ (PC-9801UV21) ##
;## 286:12MHZ (PC-9801RX2) ##
;## 386:20MHZ (PC-98RL N-MODE) ##
;## NPC:33MHZ (PC-H98 Model70) ##
;## ##
;##  注:現行機の場合、基準クロック以外では、多少誤差がでます ##
;## ##
;## 入力:CXに 待ち時間(ms)をいれる。 ##
;## 出力:なし ##
;## 破壊するレジスタ:CX、フラグ ##
;## ##
;##---------------------------------------------------------------------##
;##  変更履歴 ##
;## DATE | Ver | ##
;## -------------------------------------------------------------- ##
;## 90-04-24 | 1.00 | Original ##
;## ##
;#########################################################################
;---------------------- LOOP回数 --------------------------------------
_V30_DELAY_ EQU 550 ;V30 調整はここでやって
_286_DELAY_ EQU 1070 ;286 ください
_386_DELAY_ EQU 1600 ;386 
_DELAY_COUNT_ EQU 307 ;NPC
;--------------------------------------------------------------------------
;########################################################################
;# データ部 #
;########################################################################
;;;;; _BIOS_FLAG1_ DB 0 ;[0:458H]の内容 (del 90.10.6)
;;;;; _BIOS_FLAG2_ DB 0 ;[0:480H]の内容 (del 90.10.6)
;;;;; _CPU_ DW 0 ;現行機の、ダミーループ回数 (del 90.10.6)
;;;;; _TIME_ DW 0 ;目標時間 (del 90.10.6)
;;;;; _MUKASI_ DW 0 ;一つ前の時間 (del 90.10.6)
;************************************************************************
;* タイムスタンパ:待ち時間制御に使用するダミーループおよび *
;* I/Oリカバリータイムの保証に使用する。 *
;* ここでは、高分解能ARTICポートを用いた。 *
;* 分解能: 3.26   μs *
;* 最大値: 106.8  ms *
;* アドレス: 005C H(ワード) *
;************************************************************************
_ARTIC_LOW_ EQU 005CH ;タイムスタンパI/O port
MSR_DELAY:
PUSH AX ;使用するレジスタを退避
PUSH BX ;使用するレジスタを退避
PUSH DX ;使用するレジスタを退避
push es ; (90.10.6)
PUSH DS ;データセグメントレジスタを退避
push ds ; (90.10.6)
pop es ; (90.10.6)
;************************************************************************
;* CPUのきりわけ *
;* -------BIOSFLAGを参照する *
;************************************************************************
mov ax, 40h ;
mov ds, ax ;
;----------------NPCかどうかを判断------------------------------------
MOV AL,BYTE PTR DS:[58H] ;40:58の内容をALに入れる
MOV BYTE PTR ES:_BIOS_FLAG1_,AL
;----------------現行機のどのCPUかを判断------------------------------
MOV AL,BYTE PTR DS:[80H] ;40:80の内容をALに入れる
MOV BYTE PTR ES:_BIOS_FLAG2_,AL
MOV AL,BYTE PTR DS:[5BH] ;40:5Bの内容をALに入れる (93.03.09)
MOV BYTE PTR ES:_BIOS_FLAG3_,AL ;(93.03.09)
POP DS ;データセグメントレジスタを復帰
AND BYTE PTR _BIOS_FLAG1_,80H ;第7ビット以外を0でマスクする
JNZ _NPC_
AND BYTE PTR ES:_BIOS_FLAG3_,04H ;(93.03.09)
JNZ _NPC_ ;(93.03.09)
AND BYTE PTR _BIOS_FLAG2_,03H ;第0,1ビット以外を0でマスクする
JZ _V30_ ;第0,1ビットが「00」ならばV30
CMP BYTE PTR _BIOS_FLAG2_,01H ;第0,1ビットが「01」ならば286
JE _I286_
;########################################################################
;# 現行機の時 #
;########################################################################
_I386_: ;CPUは386
MOV WORD PTR _CPU_,_386_DELAY_ ;386の時はCPU=_386_DELAY_にする
JMP short _EXIT_CPU_
_V30_: ;CPUはV30
MOV WORD PTR _CPU_,_V30_DELAY_ ;V30の時はCPU=_V30_DELAY_にする
JMP short _EXIT_CPU_
_I286_: ;CPUは286
MOV WORD PTR _CPU_,_286_DELAY_ ;286の時はCPU=_286_DELAY_にする
_EXIT_CPU_:
;---------------------------------------------- ここからの処理で、1msと
; なるようにする
;
PUSH CX ;カウンタの内容を退避
MOV CX,_CPU_ ;CX=_CPU_
; ~~~~この値が機種ごとに変わる
_LOOP2_: ;
LOOP _LOOP2_ ;CX=CX-1 : IF ( CX == 0 ) GOTO _LOOP2_
POP CX ;カウンタの内容を復帰
;
;----------------------------------------------
LOOP _EXIT_CPU_ ;CX=CX-1 : IF ( CX == 0 ) GOTO LOOP1
pop es
POP DX ;退避したレジスタを復帰
POP BX ;退避したレジスタを復帰
POP AX ;退避したレジスタを復帰
RET ;RETURN
;########################################################################
;# NPCの時 #
;########################################################################
_NPC_:
CALL _NPC_DELAY_ ;1ms消費ルーチン
LOOP _NPC_ ;CX=CX-1
; : IF ( CX == 0 ) GOTO LOOP1
pop es ;(INS.91.1.14)
POP DX ;退避したレジスタを復帰
POP BX ;退避したレジスタを復帰
POP AX ;退避したレジスタを復帰
RET
_NPC_DELAY_:
PUSH CX
MOV DX,_ARTIC_LOW_ ;ARTICポートの内容を
;DXにいれる
IN AX,DX ;ARTICポートからAXに
;データを入れる
MOV BX,AX ;初期時間を保存
MOV CX,_DELAY_COUNT_ ;設定時間をCXに入れる
ADD CX,BX ;目標時間設定
MOV _TIME_,CX ;目標時間をCAKEに格納
JNC _POPO_
;******************************************************************************
;* 0 7FFF FFFF *
;* 1========▲-----------------1-----------×==========○============1 *
;* ↑ ↑   ↑ *
;*      目標時間:CAKE 初期時間:BX  現在時間:AX   *
;* *
;* *
;* の時 *
;* *
;******************************************************************************
MOV _MUKASI_,BX ;初期時間を_MUKASI_に入れておく
_YOMU1_:
IN AX,DX ;現在時間をAXに入れる
CMP _MUKASI_,AX ;一つ前の時間と現在の時間を比較
; 現在時間が、目標時間よりも
; 大きいため、
; 現在時間と一つ前の時間を
; 比較する。
; 現在時間が小さくなった場合
; タイムスタンパが0に戻った
; ことになる
JA _POPO_ ;現在時刻の方が小さくなった!
MOV _MUKASI_,AX ;一つ前の時間を_MUKASI_に
; 入れておく
JMP _YOMU1_ ;ループ
;******************************************************************************
;* 0 7FFF FFFF *
;* 1--------×============○====1=============▲---------------------1 *
;* ↑ ↑ ↑ *
;*  初期時間:BX   現在時間:AX    目標時間:CAKE *
;* *
;* *
;* の時 *
;* *
;******************************************************************************
_POPO_:
IN AX,DX ;現在時間をAXに入れる
CMP _TIME_,AX ;目標時間までなったか?
JA _POPO_ ;No:まだ目標時間ではない
POP CX
RET ;END NPC_RTN