Mikrosekundy vo Windows a este vo Visual Basicu?
Instrukcia RDTSC pomoze, ale vo Windows to nie je take jednoduche.
Toto som robil do UniFlashu (v Pascale - ale tam toho Pascalu je, ze )
Kód:
procedure _Delay; {v1.22}
begin
Delay(100);
end;
procedure InitTSC;assembler; {Requires Pentium or newer CPU} {v1.22}
asm
pushf {PUSHF}
cli {CLI}
dw 310fh {RDTSC}
db 66h
push ax {PUSH EAX}
call _Delay {DELAY(100)} {Delay 100ms}
dw 310fh {RDTSC}
db 66h
pop bx {POP EBX}
db 66h
sub ax,bx {SUB EAX,EBX} {Ticks elapsed ->EAX}
db 66h
mov word ptr tsc,ax {MOV TSC,EAX} {Ticks per second}
popf {POPF} {Instead of STI}
end;
{$F+}
procedure TSCWait(MicroSec:LongInt);assembler; {v1.22}
asm
dw 310fh {RDTSC}
db 66h
mov bx,ax {MOV EBX,EAX}
db 66h
mov cx,dx {MOV ECX,EDX}
db 66h
mov ax,word ptr MicroSec {MOV EAX,MicroSec}
db 66h
mul word ptr uSec {MUL uSec} {Ticks to wait ->EDX:EAX}
db 66h
add bx,ax {ADD EBX,EAX}
db 66h
adc cx,dx {ADC ECX,EDX}
@:dw 310fh {RDTSC}
db 66h
cmp dx,cx {CMP EDX,ECX} {Waiting enough?}
je @low {JE @low} {Waiting enough (high)}
ja @exit {JA @exit} {Waiting more! Exit!}
jmp @ {JMP @} {Not enough, wait more}
@low:
db 66h
cmp ax,bx {CMP EAX,EBX} {Waiting enough?}
jae @exit {JL @} {Not enough, wait more}
jmp @
@exit:
end;
{$F-}
function TSCPresent:Boolean;assembler; {v1.22}
asm
db 66h
pushf {PUSHFD}
db 66h
pop ax {POP EAX} {Read EFLAGS register to EAX}
db 66h
push ax {PUSH EAX} {Save it for later use}
db 66h
or ax,0h
dw 20h {OR EAX,200000h} {Set CPUID bit}
db 66h
push ax {PUSH EAX}
db 66h
popf {POPFD} {Put EAX to EFLAGS}
db 66h
pushf {PUSHFD}
db 66h
pop ax {POP EAX} {Read back EFLAGS to EAX}
db 66h
and ax,0h
dw 20h {AND EAX,200000h}
db 66h
cmp ax,0h
dw 20h {CMP EAX,200000h} {Is CPUID bit set?}
jne @bad {JNE @BAD} {If not, CPUID not supported}
db 66h
xor ax,ax {XOR EAX,EAX}
dw 0a20fh {CPUID} {Call level 0 CPUID}
dd 0f88366h {CMP EAX,0} {Is MaxLevel 0?}
je @bad {JE @BAD} {If yes, it's bad, we need 1}
db 66h
xor ax,ax {XOR EAX,EAX}
db 66h
inc ax {INC EAX} {MOV EAX,1}
dw 0a20fh {CPUID} {Call level 1 CPUID}
dd 10e28366h {AND EDX,10h}
db 66h
cmp dx,10h {CMP EDX,10h} {Is TSC bit set?}
jne @bad {JNE @BAD} {If not, TSC not present}
mov ax,1 {MOV AX,1} {Return TRUE}
jmp @exit
@bad:
xor ax,ax {XOR AX,AX} {Return FALSE}
jmp @exit
@exit:
db 66h
popf {POPFD} {Restore EFLAGS register}
end;
Na zaciatku to treba kalibrovat:
Kód:
InitTSC;
uSec:=TSC div 100000;
Funkcia Delay musi byt aspon trochu presna, aby to fungovalo.