; XTIMER.ASM -- The X Timer (like Zen Timer, but simpler)
; By Tenie Remmel

Ideal

Public      StartTimer, StopTimer, ReadTimer

Model Tiny
CodeSeg
P186

;*********************** Data Section

Count       dw 0                    ;Timing count
OldFlags    dw 0                    ;Saved flags

;*********************** StartTimer -- Start the X Timer

Proc        StartTimer

            pusha                   ;Save all registers
        
            pushf                   ;Save flags
            pop [cs:OldFlags]

            sti                     ;Enable interrupts

            mov al,34h              ;Set timer mode 2
            out 43h,al
            xor al,al               ;Set countdown to 0
            out 40h,al
            out 40h,al
        
            hlt                     ;Wait for interrupt
            cli                     ;Disable interrupts
        
            mov al,34h              ;Set timer mode 2
            out 43h,al
            xor al,al               ;Reset countdown
            out 40h,al
            out 40h,al
        
            popa                    ;Restore registers
            ret                     ;Return

EndP        StartTimer

;*********************** StopTimer -- Stop the X Timer

Proc        StopTimer

            pusha                   ;Save all registers

            xor al,al               ;Latch countdown value
            out 43h,al

            sti                     ;Enable interrupts

            in al,40h               ;Read countdown value
            mov ah,al
            in al,40h
            xchg ah,al              ;AX = time in ticks
            neg ax

            mov dx,88               ;Convert to microseconds
            mul dx                  ;1 tick = 88/105 microsecond
            mov bx,105
            div bx
            cmp dx,53               ;Round to nearest value
            sbb ax,-1

            mov [cs:Count],ax       ;Save count

            push [cs:OldFlags]      ;Restore old flags
            popf
            popa                    ;Restore registers
            ret                     ;Return

EndP        StopTimer

;*********************** ReadTimer -- Return timed value in AX

Proc        ReadTimer

            mov ax,[cs:Count]       ;AX = count
            ret                     ;Return

EndP        ReadTimer

End
