212 lines
7.4 KiB
NASM
212 lines
7.4 KiB
NASM
;#########################################################################
|
||
;## 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
|
||
|
||
|