
;
; Timer device test.
;
; Sorry about the lack of comments, I don't have time.
; make amigalibs.res resdident
;
; 1,000,000 (1 million) microseconds = 1 second
;


WBStartup

DEFTYPE.timerequest   *timereq
DEFTYPE.timeval       currenttime, oldtime, mytime
DEFTYPE.b error

device$ = "timer.device"


; Delete a timer
Statement delete_timer{*tr.timerequest}
  DEFTYPE.MsgPort *tp

  If *tr
    ;
    *tp = *tr\tr_node\io_Message\mn_ReplyPort
    ;
    If *tp
      DeleteMsgPort *tp
    EndIf

    CloseDevice_      *tr
    DeleteIORequest_  *tr
  EndIf

End Statement



; Create a time request
Function.l create_timer{unit.l}
  SHARED device$

  DEFTYPE.MsgPort     *timeMP
  DEFTYPE.timerequest *timeIO

  *timeMP = CreateMsgPort("")
  If *timeMP = False                ; If CreateMsgPort fails
    ;
    Function Return False
    ;
  EndIf

  *timeIO = CreateIORequest_ (*timeMP, SizeOf.timerequest)
  If *timeIO = False               ; If CreateIORequest fails
    ;
    DeleteMsgPort *timeMP
    Function Return False
    ;
  EndIf

  error.b = OpenDevice_ (&device$, unit, *timeIO, 0)
  If (NOT error)              ; OpenDevice returns 0 for success
    ;
    Function Return *timeIO
    ;
  Else
    ;
    delete_timer{*timeIO}
    Function Return False
    ;
  EndIf

End Function



; Will go to sleep for the length of time in *tv
; More precise than Delay()

Statement wait_for_timer{ *tr.timerequest, *tv.timeval}

  *tr\tr_node\io_Command = #TR_ADDREQUEST

  *tr\tr_time\tv_secs = *tv\tv_secs, *tv\tv_micro

  DoIO_ *tr
End Statement



; A time delay similar to Delay()
; When unit = #UNIT_MICROHZ you will
; get a more precise delay than when
; using unit = #UNIT_VBLANK

Function.l time_delay{*tv.timeval, unit.l}
  DEFTYPE.timerequest *tr

  *tr = create_timer{unit}

  If *tr = 0
    Function Return -1
  EndIf

  wait_for_timer{*tr, *tv}

  delete_timer{*tr}

End Function


Function.b get_sys_time{*tv.timeval}
  DEFTYPE.timerequest *tr

  *tr = create_timer{#UNIT_MICROHZ}

  If *tr = 0
    Function Return -1
  EndIf

  *tr\tr_node\io_Command = #TR_GETSYSTIME
  DoIO_ *tr

  *tv\tv_secs = *tr\tr_time\tv_secs, *tr\tr_time\tv_micro

  delete_timer{*tr}
  Function Return 0
End Function

NPrint "On your marks"
currenttime\tv_micro = 1000000     ; 1 a second
error = time_delay{&currenttime, #UNIT_VBLANK}

NPrint "Get set........."
currenttime\tv_micro LSR 1        ; 1/2 of a second
error = time_delay{&currenttime, #UNIT_VBLANK}

NPrint "GO!"
NPrint ""

result.b = get_sys_time{&oldtime}   ; get start time

; sleep for 1 second and an extra 4/50 of a second)
currenttime\tv_secs = 1
currenttime\tv_micro = 80000

error = time_delay{&currenttime, #UNIT_VBLANK}

error = get_sys_time{&mytime}                ; get end time

NPrint "Crossed the finish line"

; Subtract the old time from the new time to get the elapsed time.
; There are commands for adding/subtracting/comparing time values
; in the timer.device, but you can't make an amigalibs file for a device
; ...... yet ... :) I'm working on it

; *dest_timeval = *dest_timeval - *source_timeval

Statement SubTime{*TimerBase.l, *dest_timeval.l, *source_timeval.l}
  MOVE.l    a6,-(a7)

  MOVE.l    d0,a6
  BEQ       SubTime_exit

  MOVE.l    d1,a0
  MOVE.l    d2,a1

  JSR       -48(a6)      ; SubTime

SubTime_exit:
  MOVE.l    (a7)+,a6
  AsmExit

End Statement

*timereq = create_timer{#UNIT_VBLANK}

If *timereq
  *timebase.Library = *timereq\tr_node\io_Device

  SubTime{*timebase, &mytime, &oldtime}

  delete_timer{*timereq}
EndIf



NPrint "Elapsed : ",mytime\tv_secs, " seconds"

micros.l = mytime\tv_micro

NPrint "        : ",micros," MicroSeconds or about ",micros/20000," Ticks"

                                                   ; microseconds/20000 gives a number
MouseWait                                          ; similar to ticks per second (PAL)
                                                   ;
End                                                ; microseconds/16666 for NTSC
