When your program gets control via a timer interrupt INT 08H or INT 1cH
or the keyboard interrupt INT 09H or any asynchronously-generated event,
you must be very careful about using DOS functions.

The reason is that DOS is not reentrant.  DOS might be processing a
service call at the time of the interrupt.  If you then issue another
INT 21H, you risk disaster.

In general, when InDOS is set, you may use only DOS fns 01H-0cH (low-level
character I/O).  When it is clear, you can use all DOS fns.  An exception
occurs during INT 28H (see below).

  InDOS Detection  
Your program can check the state of the InDOS Flag as follows:
  Early on (before you need it!) use DOS fn 34H (Get InDOS addr).  Save
the value returned in ES:BX.

  Before popping up, check the byte at the InDOS address.  A non-zero
value means beware!.  When InDOS is non-zero, DOS is processing an
INT 21H service call and you must NOT use any DOS services except the
low-level character I/O fns 01H-0cH.

  INT 28H: OK to ignore InDOS  
DOS invokes INT 28H (DOS Idle) when it is waiting for keyboard input and
it takes special precautions before making the call.  It switches stacks,
making available all DOS functions except fns 01H-0cH.

Thus, your TSR can hook INT 28H and popup with almost full availability of
DOS services regardless of the InDOS setting -- you can open/read/close
files, etc.

But when taking control under INT 28H, do remember to avoid DOS fns
01H-0cH.  For instance, to display text, use fn 40H or drop down to BIOS
fn INT 10H 0eH.  If you simply must use fns 01H-0cH, you must set the
ErrorMode Flag to 1 beforehand (and use only fns 01H-0cH while it is set).

See Also: DOS fn 34H (get InDOS and ErrorMode address)
DOS fn 01H-0CH (low-level character I/O)
INT 24H (Critical Error Handler)
- -

InDOS Flag