home *** CD-ROM | disk | FTP | other *** search
/ C!T ROM 5 / ctrom5b.zip / ctrom5b / PROGRAM / ASM / ALIB30B / TIME7.ASM < prev   
Assembly Source File  |  1994-11-28  |  7KB  |  313 lines

  1.     PAGE    66,132
  2. ;******************************** TIME7.ASM  *********************************
  3. LIBSEG           segment byte public "LIB"
  4.         assume cs:LIBSEG , ds:LIBSEG
  5. ;----------------------------------------------------------------------------
  6.     include    mac.inc
  7.     extrn    word_to_dec_stdout:far
  8.     extrn    dword_to_dec_stdout:far
  9.     extrn    stdout_string:far
  10.     extrn    quad_multiply1:far
  11.     extrn    quad_divide:far
  12. ;
  13. ; General information.  This collection of timer functions use the
  14. ; 8243 timer.  The 8253 has three timers, and timer 0 is used to
  15. ; keep the system clock (attached to interrupt 8) current.  We will
  16. ; also use timer 0.  The timer 0 is accessed at port 43h (commands) and
  17. ; port 40h (data).  One timer tick is roughly 840 nano secods.
  18. ;             
  19. timer_low    equ    046ch
  20. timer_mode    equ    43h
  21. timer0        equ    40h
  22.  
  23. comment 
  24. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -(  MISC   )
  25. ;START_TIMER - start high resolution timer
  26. ;  inputs:  none
  27. ;  output:  none
  28. ; note:  the maximum time which can be measured is one hour.  code
  29. ;        fragments can be timed accuratly up to 55ms.  Programs
  30. ;        can be timed for longer periods, but interrupts have to
  31. ;        be enabled.  It is usually best to disable interrupts
  32. ;        while timing short code fragments.  For program timing
  33. ;        the reported time will include the time required to
  34. ;        service interrupts.
  35. ;
  36. ; note:  The timer functions are usually called in the following order
  37. ;           call  calibrate_timer
  38. ;           call  start_timer
  39. ;           (timed program or code here)
  40. ;           call  read_timer
  41. ;           call  convert_timer
  42. ;           call  display_timer
  43. ;
  44. ; note:  See sample program TIMER.ASM for usage hints.
  45. ;* * * * * * * * * * * * * *
  46. 
  47.     public    start_timer
  48. start_timer    proc    far
  49.     apush    ax,dx,ds
  50.     pushf
  51.     cli
  52. ;
  53. ; initialize the 8253 to count down max count of 65536 by setting zero
  54. ;
  55.     mov    al,00110100b        ;select mode
  56.     out    timer_mode,al        ;request mode
  57.     call    delay
  58.     sub    ax,ax            ;starting count
  59.     out    timer0,al
  60.     call    delay
  61.     out    timer0,al
  62. ;
  63. ; wait for timer tick before starting
  64. ;
  65.     sti
  66.     call    delay
  67.     in    al,timer0
  68.     mov    ah,al
  69. twait:    call    delay
  70.     in    al,timer0
  71.     cmp    al,ah
  72.     je    twait
  73.     call    delay
  74. ;
  75. ;wait for interrupt
  76. ;
  77.     sub    dx,dx
  78.     mov    ds,dx            ;point at seg 0
  79.     mov    dx,word ptr ds:[timer_low]
  80. ilop:    mov    ax,word ptr ds:[timer_low]
  81.     cmp    ax,dx
  82.     je    ilop
  83. ;
  84. ; restart the timer back at count of zero again.
  85. ;
  86.     mov    al,00110100b        ;select mode
  87.     out    timer_mode,al        ;request mode
  88.     call    delay
  89.     sub    ax,ax            ;starting count
  90.     out    timer0,al
  91.     call    delay
  92.     out    timer0,al
  93. ;
  94. ; get the current bios time of day
  95. ;
  96.     mov    ax,word ptr ds:[timer_low]
  97.     mov    cs:interrupt_count,ax
  98.     popf
  99.     apop    ds,dx,ax
  100.     retf
  101. start_timer    endp
  102.  
  103. delay:    jmp    d1
  104. d1:    jmp    d2
  105. d2:    jmp    d3
  106. d3:    jmp    d4
  107. d4:    ret
  108.  
  109. comment 
  110. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -(  MISC   )
  111. ;read_timer - read high resolution timer
  112. ;  inputs:  none
  113. ;  output:  dx,ax = total 8253 timer ticks at rate of 1,193,182 per second
  114. ;           
  115. ;* * * * * * * * * * * * * *
  116. 
  117.     public    read_timer
  118. read_timer    proc    far
  119.     apush    ds,es
  120.     pushf
  121.     cli
  122.     mov    ax,cs
  123.     mov    ds,ax
  124.     xor    ax,ax
  125.     mov    es,ax
  126. ;
  127. ; stop timer by setting mode to zero
  128. ;
  129.     out    timer_mode,al    ;timer interrupts off
  130.     call    delay
  131.     in    al,timer0
  132.     call    delay
  133.     mov    ah,al
  134.     in    al,timer0
  135.     xchg    ah,al
  136.     neg    ax
  137.     mov    timer_count,ax    ;ax now has 16 bit timer count
  138. ;
  139. ; read interrupt count from bios
  140. ;
  141.     mov    ax,es:[timer_low]
  142.     sub    ax,interrupt_count
  143.     mov    interrupt_count,ax
  144. ;
  145. ; restart the timer by resetting default value of control word
  146. ;
  147.     mov    al,00110110b    ;binary,mode 3,timer 0
  148.     out    timer_mode,al
  149.     mov    al,0
  150.     call    delay
  151.     out    timer0,al
  152.     call    delay
  153.     out    timer0,al
  154. ;
  155. ; return values to caller
  156. ;
  157.     mov    ax,timer_count
  158.     mov    dx,interrupt_count
  159.  
  160.     sub    ax,calibrate
  161.     sbb    dx,0            ;calibrate timer value
  162.     popf
  163. exit:    apop    es,ds
  164.     retf
  165. read_timer    endp
  166.  
  167. comment 
  168. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -(  MISC   )
  169. ;CONVERT_TIMER - convert timer ticks to seconds and microseconds
  170. ;  inputs:  dx,ax = total 8253 timer ticks at rate of 1,193,182 per second
  171. ;  output:  ax = seconds
  172. ;           cx,bx = microseconds
  173. ;
  174. ;* * * * * * * * * * * * * *
  175. 
  176.     public    CONVERT_TIMER
  177. CONVERT_TIMER    proc    far
  178.     apush    si,ds
  179.     mov    si,cs
  180.     mov    ds,si
  181.  
  182.     mov    cx,word ptr timer_convert+2
  183.     mov    bx,word ptr timer_convert
  184.     call    quad_multiply1        ;result to dx,cx,bx,ax
  185.     mov    si,word ptr hundred_thousand+2
  186.     mov    di,word ptr hundred_thousand
  187.     call    quad_divide        ;result dx,ax  remainder cx,bx
  188.  
  189. ;
  190. ; dx,ax now contains the total number of micro seconds, cx,bx = remainder
  191. ;
  192.     cmp    cx,1
  193.     je    round_up
  194.     cmp    bx,0c350h        ;(100000/2)
  195.     jb    compute_seconds
  196. round_up:
  197.     add    ax,1
  198.     adc    dx,0            ;round up 1
  199.  
  200. compute_seconds:
  201.     mov    bx,dx
  202.     xor    dx,dx
  203.     xor    cx,cx
  204.     mov    si,word ptr million+2
  205.     mov    di,word ptr million
  206.     call    quad_divide        ;compute seconds & microseconds
  207. ;
  208. ; dx,ax = seconds   cx,bx = microseconds
  209. ;
  210.     apop    ds,si
  211.     retf        
  212.  
  213. CONVERT_TIMER    endp
  214.  
  215. comment 
  216. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -(  MISC   )
  217. ;DISPLAY_TIMER - display timer values to stdout
  218. ;  inputs:   ax = seconds
  219. ;          cx,bx = microseconds
  220. ;  output:  none
  221. ;           
  222. ;* * * * * * * * * * * * * *
  223. 
  224.     public    display_timer
  225. DISPLAY_TIMER    proc    far
  226.     apush    si,ds
  227.  
  228.     mov    si,cs
  229.     mov    ds,si
  230.     mov    seconds,ax
  231.     mov    word ptr microseconds+2,cx
  232.     mov    word ptr microseconds,bx
  233.  
  234.     mov    si,offset msg1
  235.     call    stdout_string            ;display 'Elapsed time ="
  236.     
  237.     mov    ax,seconds
  238.     call    word_to_dec_stdout        ;seconds
  239.     mov    si,offset message_sec
  240.     call    stdout_string
  241.     
  242.     mov    ax,word ptr microseconds
  243.     mov    dx,word ptr microseconds+2
  244.     call    dword_to_dec_stdout
  245.     mov    si,offset message_micro
  246.     call    stdout_string
  247.     apop    ds,si
  248.     retf
  249. DISPLAY_TIMER    endp
  250. comment 
  251. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -(  MISC   )
  252. ;CALIBRATE_TIMER - calibrate timer
  253. ;  inputs:  none
  254. ;  output:  none
  255. ; note:  This function computes the overhead needed to call
  256. ;        START_TIMER and read_timer on current computer and
  257. ;        calibrates the time calculation so that it will
  258. ;        compute zero if nothing is being timed.           
  259. ;
  260. ; note:  This function only needs to be called once.  It saves
  261. ;        a calibration factor which is used by read_timer as
  262. ;        long as read_timer is in memory.
  263. ;* * * * * * * * * * * * * *
  264. 
  265.  
  266.     public    calibrate_timer
  267. calibrate_timer    proc    far
  268.     apush    ax,bx,cx,dx
  269.     mov    cs:calibrate,0
  270.     mov    cs:seconds,0
  271.     mov    cx,8
  272. ct_lp1:    push    cx
  273.            call    start_timer
  274.     call    read_timer
  275.     add    cs:seconds,ax
  276.     pop    cx
  277.     loop    ct_lp1
  278.  
  279.     mov    ax,cs:seconds
  280.     mov    cl,3
  281.     shr    ax,cl
  282.     mov    cs:calibrate,ax
  283.     
  284.     mov    cx,5000
  285. ct_lp:    call    delay
  286.     loop    ct_lp
  287.     apop    dx,cx,bx,ax
  288.     retf
  289. calibrate_timer    endp
  290. ;--------------------------------------------------------------------------
  291.  
  292. timer_count    dw    0    ;read from 8253
  293. interrupt_count    dw    0    ;read from BIOS
  294.  
  295. microseconds    dd    0    ;total microseconds
  296. seconds        dw    0    ;total seconds
  297.  
  298. calibrate    dw    0    ;calibration factor from read_timer
  299.  
  300. timer_convert    dd    83809    ;838.096 nsec per tick
  301. hundred_thousand dd    100000
  302. million        dd    1000000
  303.  
  304. msg1        db    0dh,0ah,0dh,0ah,'Elapsed time = ',0
  305. message_sec    db    ' (seconds)   ',0
  306. message_micro    db    ' (Micro seconds)',0dh,0ah,0
  307.  
  308.  
  309. LIBSEG    ENDS
  310. ;;    end
  311.