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.