Metropoli BBS
VIEWER: timer.asm MODE: TEXT (ASCII)
;this code is to test 2 tests of code to see which is faster
;place code in timer.inc, compile and run it...

;you must run this under DOS, windoze does not allow to tamper with the PIT

;NOTE : this program sets timer#0 to as fast as possible so this program
;       traps IRQ1 and does not let it go to DOS, so your time
;       will simply freeze when you use this program (instead of zooming
;       into the next millinium)

;NEW : Now takes advantage of Pentium cycle clock (opcode 0fh,31h)

; timer.inc holds the code to be timed it also 
;   holds some of my findings
; results are VERY accurate (unless you run this under an program that does
;   not allow this to alter the PIT)

include qlib.inc
include stdio.inc
include conio.inc
include alloc.inc

.data

spdhi equ 000h
spdlo equ 010h

loops equ 100000
  ;no of times to do c1,c2 each time
  ;change this to a comfortable speed for your CPU
  ;I have a P90

align 4  ;ok, I think I went align crazy here...
s1 dd 0
s2 dd 0

oldIRQ1 df ?
align 4
counter dd ?
counter2 dd ?
pre dw 100  ;it does this many times before it starts average mode

om dw ? ;old IRQ masks

.code
align 4
include timer.inc

align 4
irq1 proc
  push ds
  push ax
  mov ds,cs:seldata
  inc counter
  mov al,20h
  out 20h,al
  pop ax
  pop ds
  iretd
irq1 endp

align 4
main proc
  in al,021h
  shl ax,8
  in al,0a1h
  mov om,ax

  .if _cpu < 5
    callp getint,8
    mov wptr[oldIRQ1+4],ax
    mov dptr[oldIRQ1],edx

    mov cx,cs
    callp setint,8,cx,offset irq1

    mov al,0ffh-3
    out 021h,al   ;enable only the timer and kbd
    mov al,0ffh
    out 0a1h,al 

    ;setup a fast TIMER
    cli
    mov al,00110110b
    out 43h,al
    mov al,spdlo
    out 40h,al
    mov al,spdhi       ;1191180 = freq of timer
    out 40h,al  ;really fast
    sti
  .else   ;Pentium
    mov al,0ffh-2
    out 021h,al   ;enable only the kbd
    mov al,0ffh
    out 0a1h,al 
  .endif

  call clrscr
  callp printf,"Code #1 =\n"
  callp printf,"Code #2 =\n"
  callp printf,"Counter =\n"

align 4
top:
  .if _cpu >= 5
    db 0fh,31h  ;EDX:EAX = cycle clock
    mov counter,eax
    mov counter2,edx
  .endif
  callp gotoxy,10,3
  callp printf,"%10u",counter
  mov ecx,loops
align 4
  .if _cpu >= 5
    db 0fh,31h  ;EAX:EDX = cycle clock
    mov counter,eax
    mov counter2,edx
  .endif
  mov edx,counter
align 4
_c1:
  push ecx
  push edx
  c1
  pop edx
  pop ecx
  dec ecx
  jnz _c1
  .if _cpu >= 5
    push edx
    db 0fh,31h  ;EDX:EAX = cycle clock
    mov counter,eax
    mov eax,edx
    pop edx
    .if eax != counter2
      jmp _i1  ;ignore this last turn (counter flipped)
    .endif
  .endif
  mov ecx,counter
  .if edx>ecx
    jmp _i1  ;counter fliped so just ignore this turn
  .endif
  sub ecx,edx
  .if pre
    mov s1,ecx
  .else
    add s1,ecx
    shr s1,1
  .endif
  callp gotoxy,10,1
  callp printf,"%10u",s1
_i1:

  mov ecx,loops
align 4
  .if _cpu >= 5
    db 0fh,31h  ;EDX:EAX = cycle clock
    mov counter,eax
    mov counter2,edx
  .endif
  mov edx,counter
align 4
_c2:
  push ecx
  push edx
  c2
  pop edx
  pop ecx
  dec ecx
  jnz _c2
  .if _cpu >= 5
    push edx
    db 0fh,31h  ;EDX:EAX = cycle clock
    mov counter,eax
    mov eax,edx
    pop edx
    .if eax != counter2
      jmp _i2  ;counter flip
    .endif
  .endif
  mov ecx,counter
  .if edx>ecx
    jmp _i2  ;counter fliped so just ignore this turn
  .endif
  sub ecx,edx
  .if pre
    mov s2,ecx
    dec pre
  .else
    add s2,ecx
    shr s2,1
  .endif
  callp gotoxy,10,2
  callp printf,"%10u",s2
_i2:
  call kbhit
  cmp al,0
  jz top

  call getch

  .if _cpu < 5
    cli
    mov al,00110110b
    out 43h,al
    xor al,al
    out 40h,al
    out 40h,al  ;Default speed (18.2 / sec)
    sti

    mov cx,wptr[oldIRQ1+4]
    mov edx,dptr[oldIRQ1]
    callp setint,8,cx,edx
  .endif

  mov ax,om
  out 0a1h,al
  shr ax,8
  out 021h,al

  callp gotoxy,1,4
  ret
main endp

end

[ RETURN TO DIRECTORY ]