Back to home page

DOS ain't dead

Forum index page

Log in | Register

Back to the forum
Board view  Mix view

Waiting for 3 (or 3.3) microseconds? 286 and up. (Developers)

posted by bretjohn Homepage E-mail, Rio Rancho, NM, 10.12.2012, 15:52

Here's some code I've used in a lot of my programs to accomplish this task. It's written for A86, so you will need to change it a little depending on your assembler. You could optimize it some more if you wanted to, but it works OK just like it is.


;-----------------------------------------------------------------------------
;DELAY FOR A GIVEN NUMBER OF MICROSECONDS
;Inputs:  AX = number of microseconds to wait (0-65535)
;Outputs:
;Changes:
;   NOTE: Delays will be slightly longer than what's asked for, never shorter.
;         Accuracy decreases with small delays or slow computers!
;-----------------------------------------------------------------------------
DelayUSAX:
  PUSH AX,BX           ;Save used registers
  OR   AX,AX           ;Is there anything to do?
  JZ  >D90             ;If not, just quit
  MOV  BX,AX           ;Put it in BX
  MOV  AX,(0FFFFh/3)+1 ;Maximum time for each sub-delay
D10:                   ;Loop to here for each sub-delay
  CMP  BX,AX           ;Is it more than the maximum?
  JA  >D40             ;If so, just do the sub-delay
  MOV  AX,BX           ;If not, just do the remainder that's left
D40:                   ;Do the delay
  CALL DoDelayUS       ;Do the US Delay
  SUB  BX,AX           ;Subtract out how long we just waited
  JNZ  D10             ;If not 0 yet, do the sub-delay again
D90:                   ;We're done
  POP  BX,AX           ;Restore used registers
  RET

DoDelayUS:
  PUSH AX,BX,CX,DX ;Save used registers
  PUSHF            ;Save Flags
  SHL  AX,1        ;Multiply by 2
  MOV  BX,11932    ;Compensate for the fact
  MUL  BX          ;  that the clock frequency
  MOV  BX,10000    ;  is actually
  DIV  BX          ;  1.19318 MHz
  MOV  DX,AX       ;Save it
  CLI              ;Disable interrupts
  CALL GetTimer    ;Get the starting timer tick counter
  MOV  CX,AX       ;Save it
D20:               ;Keep looping to here until we've waited long enough
  MOV  BX,CX       ;Get the starting timer tick counter
  CALL GetTimer    ;Get the current timer tick counter
  SUB  BX,AX       ;Calculate the elapsed time
  CMP  BX,DX       ;Has it been long enough?
  JB   D20         ;If not, keep waiting
D90:               ;We're done
  POPF             ;Restore Flags
  POP  DX,CX,BX,AX ;Restore used registers
  RET

;-----------------------------------------------------------------------------
;GET CURRENT TIMER COUNTER FROM PORT 40h (THE CLOCK INTERRUPT)
;Inputs:
;Outputs: AX = Current timer counter word
;Changes:
;-----------------------------------------------------------------------------
GetTimer:
  PUSHF       ;Save flags
  CLI         ;DIsable interrupts
  MOV  AL,06h ;Bits 7:6 =  00 = Timer 0
              ;Bits 5:4 =  00 = Latch Counter
              ;Bits 3:1 = 011 = Mode 3 (Square Wave)
              ;Bit    0 =   0 = Binary Counter (16 bits)
  OUT  43h,AL ;Tell the PIT what wer'e going to do
  IN   AL,40h ;Get LSB of timer counter
  MOV  AH,AL  ;Save it
  IN   AL,40h ;Get MSB of timer counter
  XCHG AH,AL  ;Put things in the right order
  POPF        ;Restore flags
  RET

 

Complete thread:

Back to the forum
Board view  Mix view
22762 Postings in 2122 Threads, 402 registered users (0 online)
DOS ain't dead | Admin contact
RSS Feed
powered by my little forum