windows-nt/Source/XPSP1/NT/base/mvdm/wow16/drivers/neccomm1/delay.asm
2020-09-26 16:20:57 +08:00

212 lines
7.4 KiB
NASM
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

;#########################################################################
;## DELAY ルーチン ##
;##  指定された時間だけ待つルーチン(単位ms) ##
;## ##
;## 基準となるCPUクロック ##
;## Z (PC-9801UV21) ##
;## Z (PC-9801RX2) ##
;## Z (PC-98RL N-MODE) ##
;## Z (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 ; 
_DELAY_COUNT_ EQU 307 ;
;--------------------------------------------------------------------------
;########################################################################
;# データ部 #
;########################################################################
;;;;; _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ポートを用いた。 *
;* 分解能:    μs *
;* 最大値:   *
;* アドレス: 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」ならば
CMP BYTE PTR _BIOS_FLAG2_,01H ;第0,1ビットが「01」ならば
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_ ;__
; ~~~~この値が機種ごとに変わる
_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