[alt.msdos.programmer] calling tsrs in ems

djb@wjh12.harvard.edu (David J. Birnbaum) (06/08/90)

(Note: there has been a problem with reposting of old articles under new
dates in these groups.  The following is a new posting on 9 June 1990.)
========================================================================
  Is there some peculiarity to using hotkeys for tsrs in ems that didn't
make it into the documentation?  As part of an attempt to write a tsr that
could be loaded into ems and run from there, I wrote a tiny non-ems tsr
that simply beeps when a hotkey combination is depressed.  It works
flawlessly in its non-ems incarnation.

  Flushed with success, I then modified it to run from ems.  I use ems
function 24 (move/exchange memory region, ax=5700h) to copy the beeping
routine into ems as part of the installation procedure.  The hotkey
combination invokes ems function 23 (alter page map & call, ax=5600h),
which maps my routine into the page frame, executes it, and returns.  This
works flawlessly most of the time, which suggests that I am using the
correct ems functions and using them correctly.  The isr is in regular
memory; the only code located in ems is the actual beeping routine.

  But I am clearly doing something wrong, since the program sometimes fails
in a number of interesting ways.  If I lean on the hotkey combination
(producing several calls to my routine and, correspondingly, several beeps)
I can produce the following results (roughly in decreasing frequency of
occurrence):

1) Everything works correctly.

2) Everything appears to work correctly, but the next keystroke is lost.
That is, when I release the hotkeys and am sitting on the command line,
striking any key has no effect.  The system behaves normally on the
keystroke after that.

3) I get an error message for the con device.  When I select abort I am
returned to the command line.

4) I get a sudden display of garbage on the screen.  Striking random keys
eventually returns the system to order.

5) The system locks up and has to be rebooted.

  I would be grateful for any suggestions about what I might be doing
wrong.  Given that the problem occurs when I make multiple calls to my
routine, I thought it might be a reentrancy problem; I am appending the kb
interrupt handling routine, which illustrates my use of a flag (hotflag) to
prevent reentrancy.  Is there something faulty about this strategy?  Why
should it fail (sometimes, and in different ways) for the ems version of my
program and work with the non-ems version?

  I would be happy to send the entire routine, which is quite small, to
anyone interested in taking a look at it.

Thanks for any advice or suggestions,

--David
===========================================================================
David J. Birnbaum
djb@wjh12.harvard.edu [Internet]      djb@harvunxw.bitnet [Bitnet]
===========================================================================

; new kb interrupt routine
; hotflag is initialized to 0

new_int9:
  pushf
  call  cs:[old_int9]           ;call old int 9
  test  cs:[hotflag],1          ;is hot flag set?
  jnz   int9_exit               ;if so, we're already up
  inc   cs:[hotflag]            ;set hotflag to avoid recursive entry
  push  ax                      ;save ax before changing it
  mov   ah,2                    ;get keyboard status byte
  int   016
  and   al,3                    ;mask for both shift keys (hot key combo)
  cmp   al,3                    ;are both shift keys down?
  pop   ax                      ;restore saved ax
  jne   not_hotkeys             ;if not, just exit

; the following code is only executed if the hotkey combination is detected

  push  ds                      ;save for exit
  mov   ax,cs                   ;segment for tsr
  mov   ds,ax                   ;point ds to our tsr

; for this posting I have omitted the specific setup for alter page
; map & call, which goes here

  mov   ax,05600                ;map & call (physical page mode)
  int 067
  pop ds                        ;restore original ds before exit

not_hotkeys:
  dec   cs:[hotflag]            ;clear hotflag when we exit
int9_exit:
  iret

===========================================================================
; the following is the beeping routine, which is copied into ems by the
; installation module and called whenever the hotkey combination is
; detected

routine:
  mov   ax,0e07                 ;output char 7 (beep)
  xor   bh,bh                   ;page 0
  int   010
  retf