mirror of https://github.com/tongzx/nt5src
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
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
|
|
|
|
|