; wir starten an 0x7c00, weil wir ja direkt gebootet werden.
org 0x7c00
; keine interrupts
cli
; erstmal initialisieren wir ein paar variablen, naemlich den low-teil des
; anfangs-prozessortaktzaehlers, den high-teil desselbigen, je 32 bit, also
; ein double-word. dann definieren wir die abzuwartenden takte, und den daraus
; resultieren wert, der am ende im lsb bzw msb stehen soll.
LSB_start dd 0
MSB_start dd 0
MS_count_small dd 200000
MS_count_big dd 2500000
LSB_end dd 0
MSB_end dd 0
schleife:
; den parport anschalten
mov dx, 888
mov al, 255
out dx, al
; erstmal schreiben wir die anzahl der bisher vergangenen cpu-takte nach
; edx:eax
rdtsc
; unnoetig, weil wirs nicht mehr verwenden werden.
; ; dann sichern wir den high-teil nach msb_start, den low-teil nach lsb.
; mov [MSB_start], edx
; mov [LSB_start], eax
; jetzt fuegen wir die anzahl der zu wartenden takte zu eax hinzu und sichern
; das ergebnis nach lsb_end, das ist der wert, den der lsb am ende haben soll.
add eax, MS_count_small
mov [LSB_end], eax
; wenn das carry-flag gesetzt ist, sprich es einen uebertrag gab, ist der
; msb_end msb_start + 1, sonst msb_end.
mov [MSB_end], edx
jnc warteklein
mov eax, edx
add eax, 1
mov [MSB_end], eax
; nun muessen wir warten, bis der low-teil von rdtsc >= lsb_end und der
; highteil = msb_end ist.
warteklein:
; wieder die vergangenen takte nach edx:eax
rdtsc
; die takte, die vergehen sollen, nach ebx
mov ebx, LSB_end
; wenn lsb_current in eax groesser ist als lsb_end in ebx, dann schaue ich
; noch, ob msb_current = msb_end, und wenn das auch noch zutrifft, dann kann
; ich weitermachen. wenn lsb_current < lsb_end, dann kann ich gleich von
; vorn anfangen.
cmp eax, ebx
jb warteklein
; msb_end nach ecx
mov ecx, MSB_end
; den aktuellen msb und den soll-msb vergleichen
cmp edx, ecx
; wenn die beiden nicht gleich gross sind, dann nach warteklein huepfen.
jne warteklein
;-----------------------------------------------------------------------
; den parport ausschalten
mov dx, 888
mov al, 0
out dx, al
; erstmal schreiben wir die anzahl der bisher vergangenen cpu-takte nach
; edx:eax
rdtsc
; unnoetig, weil wirs nicht mehr verwenden werden.
; ; dann sichern wir den high-teil nach msb_start, den low-teil nach lsb.
; mov [MSB_start], edx
; mov [LSB_start], eax
; jetzt fuegen wir die anzahl der zu wartenden takte zu eax hinzu und sichern
; das ergebnis nach lsb_end, das ist der wert, den der lsb am ende haben soll.
add eax, MS_count_big
mov [LSB_end], eax
; wenn das carry-flag gesetzt ist, sprich es einen uebertrag gab, ist der
; msb_end msb_start + 1, sonst msb_end.
mov [MSB_end], edx
jnc wartegross
mov eax, edx
add eax, 1
mov [MSB_end], eax
; nun muessen wir warten, bis der low-teil von rdtsc >= lsb_end und der
; highteil = msb_end ist.
wartegross:
; wieder die vergangenen takte nach edx:eax
rdtsc
; die takte, die vergehen sollen, nach ebx
mov ebx, LSB_end
; wenn lsb_current in eax groesser ist als lsb_end in ebx, dann schaue ich
; noch, ob msb_current = msb_end, und wenn das auch noch zutrifft, dann kann
; ich weitermachen. wenn lsb_current < lsb_end, dann kann ich gleich von
; vorn anfangen.
cmp eax, ebx
jb wartegross
; msb_end nach ecx
mov ecx, MSB_end
; den aktuellen msb und den soll-msb vergleichen
cmp edx, ecx
; wenn die beiden nicht gleich gross sind, dann nach warteklein huepfen.
jne wartegross
jmp schleife
times 512-($-$$)-2 db 0
dw 0AA55h