204 |
miho |
1 |
unit Delay; |
|
|
2 |
|
|
|
3 |
{-----------------------------------------------------------------} |
|
|
4 |
{ Definovane spozdeni, ktere funguje i na } |
|
|
5 |
{ vykonnejsich pocitacich } |
|
|
6 |
{ } |
|
|
7 |
{ Verze 1.0 portovano by miho 96 } |
|
|
8 |
{ 1.1 popora kratkych casu miho 98 } |
|
|
9 |
{ 1.2 podpora rychlych CPU ( rozsireni DelayCnt1 na DWORD ) } |
|
|
10 |
{-----------------------------------------------------------------} |
|
|
11 |
|
|
|
12 |
{$I-,S-} |
|
|
13 |
|
|
|
14 |
interface |
|
|
15 |
|
|
|
16 |
|
|
|
17 |
procedure xDelay(MS: Word); |
|
|
18 |
{-- cas uveden v milisekundach --} |
|
|
19 |
|
|
|
20 |
|
|
|
21 |
procedure xDelayMicro(MicroS: Word); |
|
|
22 |
{-- cas uveden v mikrosekundach --} |
|
|
23 |
{ POZOR: Casy jsou vzdy o neco delsi a za normalnich podminek } |
|
|
24 |
{ je cas delsi radove o nekolik mikrosekund } |
|
|
25 |
{ ( na PC Pentium 75 to dela cca 6us ). } |
|
|
26 |
|
|
|
27 |
|
|
|
28 |
implementation |
|
|
29 |
|
|
|
30 |
|
|
|
31 |
var DelayCnt1:longint; { kalibrace casu po 1 ms } |
|
|
32 |
DelayCnt55:longint; { totez pred vydelenim 55 } |
|
|
33 |
|
|
|
34 |
|
|
|
35 |
procedure DelayLoop; |
|
|
36 |
begin |
|
|
37 |
asm |
|
|
38 |
@@Loop: SUB AX,1 { DX:AX - pocitadlo DWORD } |
|
|
39 |
SBB DX,0 { dekrement } |
|
|
40 |
JC @@End { doteklo } |
|
|
41 |
CMP BL,ES:[DI] { pri uplynuti tiku ( 55ms ) } |
|
|
42 |
JE @@Loop { taky koncim } |
|
|
43 |
@@End: |
|
|
44 |
end; |
|
|
45 |
end; |
|
|
46 |
|
|
|
47 |
|
|
|
48 |
procedure Initialize; |
|
|
49 |
{-- inicializace - kalibrace casu --} |
|
|
50 |
begin |
|
|
51 |
asm |
|
|
52 |
MOV AX,40H { adresa bunky BIOS DATA s tiky } |
|
|
53 |
MOV ES,AX { po 55 ms aktualizuje BIOS } |
|
|
54 |
MOV DI,6CH |
|
|
55 |
MOV BL,ES:[DI] |
|
|
56 |
@@Wait: CMP BL,ES:[DI] |
|
|
57 |
JE @@Wait { pockej na cely tik } |
|
|
58 |
MOV BL,ES:[DI] { schovej si tik do BL } |
|
|
59 |
MOV AX,-28 { piskvorcova konstanta ? asi } |
|
|
60 |
CWD |
|
|
61 |
CALL DelayLoop { pockej na konec tiku BL } |
|
|
62 |
NOT AX { a pocitej cas v DS:AX} |
|
|
63 |
NOT DX |
|
|
64 |
MOV word ptr [DelayCnt55],AX { uschovej kalibraci } |
|
|
65 |
MOV word ptr [DelayCnt55+2],DX |
|
|
66 |
end; {asm} |
|
|
67 |
DelayCnt1:=DelayCnt55 div 55; { uschovej kalibraci 1 ms } |
|
|
68 |
end; {Initialize} |
|
|
69 |
|
|
|
70 |
|
|
|
71 |
procedure xDelay(MS: Word); |
|
|
72 |
{-- proved standardni spozdeni merene v milisekundach --} |
|
|
73 |
begin |
|
|
74 |
asm |
|
|
75 |
MOV CX,MS { pocet milisekund } |
|
|
76 |
JCXZ @@End { nulova hodnota - hned konci } |
|
|
77 |
MOV AX,40H { adresa BIOS COM port - to je } |
|
|
78 |
MOV ES,AX { jakakoli bunka, ktera se v } |
|
|
79 |
XOR DI,DI { v provozu nemeni aby se netestoval } |
|
|
80 |
MOV BL,ES:[DI] { casovac a presto mohla byt } |
|
|
81 |
@@Loop: MOV AX,word ptr [DelayCnt1] { procedura DelayLoop stejna } |
|
|
82 |
MOV DX,word ptr [DelayCnt1+2] { DX:AX kalibracni konsatnta } |
|
|
83 |
CALL DelayLoop { pro spozdeni 1 ms } |
|
|
84 |
LOOP @@Loop |
|
|
85 |
@@End: |
|
|
86 |
end; {asm} |
|
|
87 |
end; {xDelay} |
|
|
88 |
|
|
|
89 |
|
|
|
90 |
procedure xDelayMicro(MicroS: Word); |
|
|
91 |
{-- procedura pro spozdeni zadavane v mikrosekundach --} |
|
|
92 |
label Error; |
|
|
93 |
begin {-- prepocitej zadany cas na pocet cyklu --} |
|
|
94 |
asm |
|
|
95 |
{-- DWORD * WORD / WORD -> DWORD --} |
|
|
96 |
SUB DX,DX |
|
|
97 |
MOV AX,WORD PTR[DelayCnt55+2] |
|
|
98 |
MOV BX,55000 |
|
|
99 |
MOV CX,MicroS |
|
|
100 |
DIV BX |
|
|
101 |
PUSH DX |
|
|
102 |
MUL CX |
|
|
103 |
MOV DI,DX |
|
|
104 |
AND DX,DX |
|
|
105 |
POP DX |
|
|
106 |
JNZ Error |
|
|
107 |
MOV AX,WORD PTR[DelayCnt55] |
|
|
108 |
DIV BX |
|
|
109 |
PUSH DX |
|
|
110 |
MUL CX |
|
|
111 |
MOV SI,AX |
|
|
112 |
ADD DI,DX |
|
|
113 |
POP AX |
|
|
114 |
JC Error |
|
|
115 |
MUL CX |
|
|
116 |
DIV BX |
|
|
117 |
ADD SI,AX |
|
|
118 |
ADC DI,0 |
|
|
119 |
PUSH SI |
|
|
120 |
PUSH DI |
|
|
121 |
{-- vlastni spozdeni --} |
|
|
122 |
MOV AX,40H { opet konstantni bunka } |
|
|
123 |
MOV ES,AX |
|
|
124 |
XOR DI,DI |
|
|
125 |
MOV BL,ES:[DI] |
|
|
126 |
POP DX { DX:AX cas v poctech cyklu } |
|
|
127 |
POP AX |
|
|
128 |
CALL DelayLoop |
|
|
129 |
end; {asm} |
|
|
130 |
exit; |
|
|
131 |
asm |
|
|
132 |
Error: MOV AX,0FFFFH |
|
|
133 |
MOV DX,AX |
|
|
134 |
CALL DelayLoop |
|
|
135 |
end; {asm} |
|
|
136 |
end; |
|
|
137 |
|
|
|
138 |
|
|
|
139 |
begin Initialize; { udelej kalibraci } |
|
|
140 |
end. |