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