delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/1998/01/15/11:52:03

From: "Anthony.Appleyard" <MCLSSAA2 AT fs2 DOT mt DOT umist DOT ac DOT uk>
Organization: Materials Science Centre
To: djgpp-workers AT delorie DOT com
Date: Thu, 15 Jan 1998 16:42:50 GMT
Subject: MCLSSAA2 : hooking interrupt 9
Reply-to: Anthony DOT Appleyard AT umist DOT ac DOT uk
Message-ID: <4679C27AA@fs2.mt.umist.ac.uk>

  On Wed 14 Jan 1998 18:01:21 +0200 (IST) Eli Zaretskii wrote:-
>> + enum{        /* numbers of the keys */
>> +   k_esc = 1, ...
> Why are these needed on a system-wide header? ... <keys.h> already has
> definitions for all the PC keys ... add your definitions there, not to
> <sys/exceptn.h>.

  Now in <keys.h>. With thanks for the help and comments.

>> +    cli                             /* disable interrupts */
> I think this is both slow and unnecessary. Charles Sandmann agrees with
> that, so I think this line should go away.

  If int (*_djgpp_kbd_callback)(int X) points to a user function, it will be
called by the int09 hook routine and may take a while longer to run than the
default routine alone. If so, if there are two keyboard events very close
together (e.g. the user presses two keys at once), the second keypress may try
to call the int09 routine for itself partway through the first keypress's
int09 routine call. The effect of the `cli' only lasts until the next `popf'.
  I have put more pushes and pops around the call of *_djgpp_kbd_callback.

>> +    movw   __go32_info_block+26,%ax
>> +    movw   %ax,%fs                  /* FS = _dos_ds */
>> +    .byte  0x64                     /* use segment reg FS */
>> +    movw   0417,%ax                 /* [0x417] [0x418] are shift status */

> I already asked why do you need to do this when the original handler code
> already loads the _dos_ds selector into DS, two lines after you call the
> callback code. Moving that line higher is all you need to do, no?

  The original handler code runs in conventional memory mode by changing DS to
_dos_ds and restoring it afterwards. _calldjgpp_kbd_callback calls the user
function *__djgpp_kbd_callback and thus needs DS to be as for normal running.

>>   Herewith a .TXH file for it, say call it djgppkbh.txh :-
> This needs more work in the markup. Below is a somewhat changed version
> which shows what you missed. Some noteworthy comments:

  Points taken. Thank you for letting me take up your time.

> In this case, you haven't locked the code and the data, and it would surely
> crash, since it is called from within an interrupt handler. (Neither did you
> mention this in the description.)

  In my ventures so far into writing interrupt matter (using
_go32_dpmi_allocate_real_mode_callback_retf and
_go32_dpmi_chain_protected_mode_interrupt_vector), I got away without locking,
probably because the areas of store involved were small and often used and
thus DPMI likely happened to keep them always in RAM anyway.

> One thing which is definitely not right is that GCC assumes SS == DS, which
> is incorrect in the interrupt handler, so the callback code should take care
> of that also.

  I now save all possibe registers (segment and otherwise) before calling the
user function and restore them afterwards. The software does not alter DS
until after the user function has been called.

  Herewith DIFF files for:-
  include\keys.h
  include\sys\exceptn.h
  src\libc\go32\exceptn.s

  and a new .TXH file

==================================================================

*** exceptn.h	Mon Dec  4 22:39:44 1995
--- exceptn2.h	Thu Jan 15 15:40:52 1998
***************
*** 27,32 ****
--- 27,33 ----
  #define __djgpp_exception_state (*__djgpp_exception_state_ptr)
  #endif
  
+ extern int (*_djgpp_kbd_callback)(int X);
  extern unsigned short __djgpp_our_DS;
  extern unsigned short __djgpp_app_DS;	/* Data selector invalidated by HW ints */
  extern unsigned short __djgpp_ds_alias;	/* Data selector always valid */

==================================================================

*** exceptn.s	Mon Jan 12 14:54:06 1998
--- exceptn2.s	Thu Jan 15 14:28:24 1998
***************
*** 284,292 ****
--- 284,335 ----
  	iret
  
  	.align 4
+ 	.global	__djgpp_kbd_callback
+ __djgpp_kbd_callback:	.int 0	/* int (*_djgpp_kbd_callback)(int X); */
+ /* If not 0, the interrupt 9 hook routine will call this function with:- */
+ /*  X     &255 == keyboard event */
+ /* (X>> 8)&255 == keyboard shift status as if from (AH=2, int 16h) */
+ /* (X>>16)&255 == keyboard extended shift status as if from (AH=12h, int 16h) */
+ _calldjgpp_kbd_callback:
+ 	xorl %eax,%eax			/* must return 0 if no function */
+ 	pushl %ebx			/* save EBX */
+ 	movl __djgpp_kbd_callback,%ebx
+ 	testl %ebx,%ebx			/* if zero, there is no function */
+ 	je no_user_hdlr
+ 	cli				/* disable interrupts until popf */
+ 	pushw %fs
+ 	movw   __go32_info_block+26,%ax
+ 	movw   %ax,%fs			/* FS = _dos_ds */
+ 	.byte  0x64			/* use segment reg FS */
+ 	movw   0417,%ax			/* [0x417] [0x418] are shift status */
+ 	sall   $8,%eax			/* move EAX one byte up */
+ 	inb    $0x60,%al		/* read keyboard event into AL */
+ 	pushw  %ds			/* save everything */
+ 	pushw  %es
+ 	pushw  %gs
+ 	pushal
+ 	pushl  %eax			/* parameter for call */
+ 	call   *%ebx			/* call the user function */
+ 	testl  %eax,%eax	/* the flags will survive the pops & the ret */
+ 	popal				/* restore everything */
+ 	popw   %gs
+ 	popw   %es
+ 	popw   %ds
+ 	popw   %fs
+ no_user_hdlr:
+ 	popl   %ebx
+ 	ret
+ 
  	.global	___djgpp_kbd_hdlr
  ___djgpp_kbd_hdlr:
  	pushl	%eax
+ 	call	_calldjgpp_kbd_callback /* If djgpp_kbd_callback returns */
+ 	je	call_default_fn	/* nonzero, no default handling of the event */
+ 	movb    $0x20,%al			/* EOI the interrupt */
+ 	outb    %al,$0x020
+ 	popl    %eax
+ 	iret
+ call_default_fn:
  	pushl	%ds
     	.byte	0x2e				/* CS: */
  	testb	$1, ___djgpp_hwint_flags	/* Disable? */
***************
*** 317,322 ****
--- 360,372 ----
  	.global	___djgpp_kbd_hdlr_pc98
  ___djgpp_kbd_hdlr_pc98:
  	pushl	%eax
+ 	call	_calldjgpp_kbd_callback /* If djgpp_kbd_callback returns */
+ 	je	call_default	/* nonzero, no default handling of the event */
+ 	movb    $0x20,%al			/* EOI the interrupt */
+ 	outb    %al,$0x020
+ 	popl	%eax
+ 	iret
+ call_default:
  	pushl	%ds
     	.byte	0x2e				/* CS: */
  	testb	$1, ___djgpp_hwint_flags	/* Disable? */

==================================================================

*** keys.h	Mon Aug 12 21:58:02 1996
--- keys2.h	Thu Jan 15 10:11:40 1998
***************
*** 250,255 ****
--- 250,367 ----
  #define K_Control_EInsert      0x292
  #define K_Control_EDelete      0x293
  
+ /* Raw values of keyboard key-press events. Add 128 to get key-release values */
+ 
+ #define k_esc           0x01
+ #define k_1             0x02
+ #define k_2             0x03
+ #define k_3             0x04
+ #define k_4             0x05
+ #define k_5             0x06
+ #define k_6             0x07
+ #define k_7             0x08
+ #define k_8             0x09
+ #define k_9             0x0A
+ #define k_0             0x0B
+ #define k_1rof0         0x0C
+ #define k_2rof0         0x0D
+ #define k_backspace     0x0E
+ #define k_tab           0x0F
+ #define k_Q             0x10
+ #define k_W             0x11
+ #define k_E             0x12
+ #define k_R             0x13
+ #define k_T             0x14
+ #define k_Y             0x15
+ #define k_U             0x16
+ #define k_I             0x17
+ #define k_O             0x18
+ #define k_P             0x19
+ #define k_1rofP         0x1A
+ #define k_2rofP         0x1B
+ #define k_enter         0x1C
+ #define k_lctrl         0x1D
+ #define k_A             0x1E
+ #define k_S             0x1F
+ #define k_D             0x20
+ #define k_F             0x21
+ #define k_G             0x22
+ #define k_H             0x23
+ #define k_J             0x24
+ #define k_K             0x25
+ #define k_L             0x26
+ #define k_1rofL         0x27
+ #define k_2rofL         0x28
+ #define k_1lof1         0x29
+ #define k_lshift        0x2A
+ #define k_3rofL         0x2B
+ #define k_Z             0x2C
+ #define k_X             0x2D
+ #define k_C             0x2E
+ #define k_V             0x2F
+ #define k_B             0x30
+ #define k_N             0x31
+ #define k_M             0x32
+ #define k_1rofM         0x33
+ #define k_2rofM         0x34
+ #define k_3rofM         0x35
+ #define k_rshift        0x36
+ #define k_padstar       0x37
+ #define k_lalt          0x38
+ #define k_space         0x39
+ #define k_capslock      0x3A
+ #define k_F1            0x3B
+ #define k_F2            0x3C
+ #define k_F3            0x3D
+ #define k_F4            0x3E
+ #define k_F5            0x3F
+ #define k_F6            0x40
+ #define k_F7            0x41
+ #define k_F8            0x42
+ #define k_F9            0x43
+ #define k_F10           0x44
+ #define k_numlock       0x45
+ #define k_scrolllock    0x46
+ #define k_pad7          0x47
+ #define k_pad8          0x48
+ #define k_pad9          0x49
+ #define k_padminus      0x4A
+ #define k_pad4          0x4B
+ #define k_pad5          0x4C
+ #define k_pad6          0x4D
+ #define k_padplus       0x4E
+ #define k_pad1          0x4F
+ #define k_pad2          0x50
+ #define k_pad3          0x51
+ #define k_pad0          0x52
+ #define k_paddot        0x53
+ #define k_sysreq        0x54
+ #define k_1lofZ         0x56
+ #define k_F11           0x57
+ #define k_F12           0x58
+ 
+ /* Keyboard events that return 0xe0 and then the code modulo 256 */
+ 
+ #define k_padenter      0x11c
+ #define k_rctrl         0x11d
+ #define k_numshift      0x12a
+ #define k_padslash      0x135
+ #define k_prtscr        0x137
+ #define k_ralt          0x138
+ #define k_home          0x147
+ #define k_uparrow       0x148
+ #define k_pageup        0x149
+ #define k_leftarrow     0x14b
+ #define k_rightarrow    0x14d
+ #define k_end           0x14f
+ #define k_downarrow     0x150
+ #define k_pagedown      0x151
+ #define k_insert        0x152
+ #define k_delete        0x153
+ #define k_lwin          0x15b
+ #define k_rwin          0x15c
+ #define k_menu          0x15d
+ 
  #endif /* !_POSIX_SOURCE */
  #endif /* !__STRICT_ANSI__ */
  #endif /* !__dj_ENFORCE_ANSI_FREESTANDING */

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019