Einzelnen Beitrag anzeigen

neolithos

Registriert seit: 31. Jul 2003
Ort: Dresden
1.386 Beiträge
 
Delphi 7 Architect
 
#1

Delay Probleme auf 1 GHz Rechner

  Alt 4. Dez 2003, 21:21
Ich habe versucht eine Delay-Funktion für eine schnellen Prozessor zu kreiren, doch habe ich Probleme mit der Routine "Calibrate_Delay", die scheinbar einen "sich verzählt"

Ich habe versucht die Routine DelayOneMs zu "strecken", da sonst ein 16 Bit Wert nicht ausreicht!

Code:
   ;***************************************
   ;   Delay-Funktionen
   ;***************************************

Delay:
   ;
   ; Warte cx Millisekunden
   ;
    jcxz Delay_2      ; falls cx = 0 -> abbruch
Delay_1:
   call DelayOneMs
   loop Delay_1      ; Warte cx millisekunden
Delay_2:
   ret

DelayOneMs:               
   ;
   ; Warte für die Zeit einer Millisekunde
   ;
                     ; call = 19 TZ
   push cx               ; = 11 TZ

   mov cx, [wDelayOneMs]   ; = 8 TZ
DelayOneMs_1:
   push cx               ; = 11 TZ
   mov cx, 0FFFFh         ; = 8 TZ
DelayOneMs_2:
   nop                  ; = cx * 65536 * 3 TZ
   loop DelayOneMs_2      ; = cx * 65536 * 17 + 5 TZ
   pop cx               ; = cx * 5 TZ
   loop DelayOneMs_1      ; = cx * 17 + 5 TZ

   pop cx               ; = 8 TZ
   ret                  ; = 16 TZ
   ; TZ == 86 + cx * 65536 * 20

Calibrate_Delay:
   ;
   ; Initialisiert eine Millisekunde
   ;
   push ax
   push cx
   push dx
   push es   

   mov ax, 40h
   mov es, ax            ; es - Segment für BIOS-Datenbereich
   mov di, 6Ch            ; es:di zeigt auf Low-Wort des BIOS-Timer-Count

   mov [wDelayOneMs], WORD 1 ; Init
   mov ax, [es:di]         ; ax = Low-Wort des BIOS-Timer-Count
     
Calibrate_Delay_1:         ; Synchronisation mit System-Timer
   cmp ax, [es:di]         ; Hat sich der Wert geändert?
   je Calibrate_Delay_1   ; alter = neuer -> warte
   
   mov ax, [es:di]         ; Setze hin
     
   xor dx, dx
Calibrate_Delay_2:         ; Nun kann wDelayOneMS berechnet werden
   call DelayOneMs         ; Warte ein bißchen 200000 TZ
   inc dx               ; Inkrementier Schläfenzähler
   cmp ax,[es:di]         ; Hat sich der Wert geändert?
   je Calibrate_Delay_2
   
   ; in DX steht wert für 55ms
   mov ax, dx
   xor dx, dx
   mov bx, 55
   div bx
   
   mov [wDelayOneMs], ax  ; setze den Schleifenzähler
   
   pop es
   pop dx
   pop cx
   pop ax
   
   ret

wDelayOneMs:
   dw 0
Dieser Ausschnitt gehört zu einem Versuch von mir an meiner FH.
Dieses Programm lauft nur unter dem Basic Input Output System.
Es können demnach nur BIOS-Interrupts verwendet werden.
- ciao neo -
Es gibt niemals dumme Fragen, sondern nur dumme Antworten!
  Mit Zitat antworten Zitat