home *** CD-ROM | disk | FTP | other *** search
- PAGE 96,132
- ;**********************************************************************
- ; DELMC.ASM Clipper UDF to delay n timer ticks
- ; Author..: Sal Ricciardi
- ;
- ; Use this file for program delays that are the same regardless
- ; of CPU type and speed. Relies on the BIOS timer tick count.
- ; Maximum delay is 65535 ticks (about 1 hr). Does not validate
- ; passed parameters.
- ;
- ; This version should work better under multitasking systems like
- ; Desqview or Microsoft Windows.
- ;
- ; Usage:
- ;
- ; DELAY(10*18.2) && for 10 seconds
- ;
- ; Create .OBJ with: TASM delmc (Borland Turbo Assembler 2.5)
- ;
- ; To link into your Clipper 5 app:
- ; RTLINK FILE yourapp.obj, DELMC.OBJ LIB CLIPPER, EXTEND
- ;
- ; To link into your Clipper Summer 87 app:
- ; PLINK86 FILE yourapp.obj, DELMC.OBJ LIB CLIPPER, EXTEND
- ;
- ;**********************************************************************
- .MODEL LARGE
- EXTRN __parni:FAR, __ret:FAR
- PUBLIC delay
- .CODE
-
- Timerhigh EQU WORD PTR ds:[06eh]
- Timerlow EQU WORD PTR ds:[06ch]
-
- delay PROC FAR ;entry point
- push ax ;save registers
- push bx ;
- push cx ;
- push dx ;
- push es ;
- push ds ;
- mov ax,1 ;routine to get a numeric
- push ax ;parameter from Clipper,
- call __parni ;converted to an int in
- add sp,2 ;ax
- mov cx,ax ;put it in cx
- jcxz d999 ;skip if cx==0
- mov ax,040h ;
- mov ds,ax ;ds == 040h
- ;
- ; Get current timer count. Make sure we get both low and high at the same time.
- ;
- cli ;interrupts off
- mov ax,Timerlow ;get current tick count low
- mov dx,Timerhigh ;get current tick count high
- sti ;interrupts on
- ;
- ; Add the delay value to form the target timer count.
- ;
- add ax,cx ;add ticks parameter to form
- adc dx,0 ;target
- ;
- cmp dx,018h ;q. target past midnight?
- jb d500 ;a. no, handle normally
- ja d400 ;a. yes, go handle special case
- ;
- cmp ax,0B0h ;q. target past midnight?
- jb d500 ;a. no, handle normally
- ;
- ; Target is past midnight. Adjust target and wait for midnight.
- ;
- d400:
- sub ax,0B0h ;subtract max to adjust the
- sbb dx,018h ;target
- d410: ;is past midnight
- cmp Timerhigh,016h ;q. cross midnight yet?
- jae d410 ;a. no,loop
- ;
- ; Delay until target time. This is where we attempt some level of insulation
- ; from multitasker interruption.
- ;
- d500:
- cmp Timerhigh,dx ;q. timerhigh reach the target?
- je d510 ;a. yes, check timerlow
- ;
- ; Timerhigh could be greater than target if a multitasker had
- ; control for awhile, and we just returned
- ;
- ja d999 ;a. greater than, we're done
- ;
- ; Could be less than by more than one if multitasker had control for awhile,
- ; and during that time midnight passed
- ;a. timerhigh is less than target
- mov bx,dx ;get target in bx
- sub bx,Timerhigh ;subtract current timerhigh
- ;
- cmp bx,1 ;q. more than one less?
- jne d999 ;a. yes, must be done
-
- jmp d500 ;a. go check again
- d510: ;
- cmp Timerlow,ax ;q. timerlow less than target?
- jb d510 ;a. yes, loop
- ;
- ; Clean up and return to caller
- ;
- d999: ;
- call __ret ;post NIL return value
- pop ds ;restore ds
- pop es ;restore registers
- pop dx ;
- pop cx ;
- pop bx ;
- pop ax ;
- ret ;return to caller
- delay ENDP
- END