INT 15h AH=86h returns after the given time has passed. CX:DX is a 32-bit count of microseconds, so one second is 1 000 000 = 000F4240h: CX = 000Fh, DX = 4240h. The BIOS programs the real-time clock to interrupt 1024 times a second (IRQ 8), counts the time down in that interrupt, and lets the caller wait with interrupts enabled, so the timer, the keyboard and the mouse keep working during the wait.
It is the simple way to pause independent of the CPU speed, where a counting loop would run ten times faster on a faster machine. The examples in this chapter use it to keep a picture on the screen for a moment before switching the video mode back.
MOV DX, OFFSET WAITING1MOV AH, 09h ; DOS: print the $-string at DS:DXINT 21hMOV CX, 000Fh ; CX:DX = 1,000,000 microseconds = 000F4240hMOV DX, 4240hMOV AH, 86h ; BIOS: waitINT 15hMOV DX, OFFSET DONE1JNC SHOW1 ; CF = 0: the time has passedMOV DX, OFFSET BUSY1SHOW1:MOV AH, 09hINT 21hWAITING1 DB "waiting one second... $"DONE1 DB "done", 13, 10, "$"BUSY1 DB "not supported here", 13, 10, "$"
Resolution and limits
The RTC interrupt comes every 976 µs, so the wait is rounded up to about a millisecond: asking for 10 µs waits a millisecond. For short exact delays programs read the timer chip (port 40h) instead. The longest wait is 4295 seconds. Only one wait can run at a time; a second call while one is active (from an interrupt handler, say) returns CF = 1 immediately. The PC and XT have no RTC and no such function.
Pitfalls
The wait needs IRQ 8, which goes through the second interrupt controller and IRQ 2 of the first. A program that masks IRQ 2 or IRQ 8 at the 8259 (port 21h or A1h) makes the wait last forever on many BIOSes; DOSBox-X warns about this in its log and has an option to unmask them. Do not call it from inside a hardware interrupt handler: the handler would block every interrupt of lower priority for the whole wait.