www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1997/02/03/07:40:23

From: Paul Lay <play AT nortel DOT co DOT uk>
Newsgroups: comp.os.msdos.djgpp
Subject: real mode int slower????
Date: Mon, 03 Feb 1997 11:49:33 +0000
Organization: Nortel Limited
Lines: 295
Message-ID: <32F5D0CD.41C67EA6@nortel.co.uk>
NNTP-Posting-Host: bhl3s9d.bnr.co.uk
Mime-Version: 1.0
To: djgpp AT delorie DOT com
DJ-Gateway: from newsgroup comp.os.msdos.djgpp

I've just turned a protected mode interrupt into a real mode one,
looking 
for a performance gain but instead things got worse...

I'm using the timer interrupt (0x08) to read the joystick. What I do is
increase the timer frequency to around 6kHz and install a new isr that 
monitors the joystick, building up its x and y positions (at this rate
you 
get ranges of 0..9 for both x and y positions). In order to maintain the
time of day and whatever else is done during the normal timer interrupt,
I
periodically chain to the old timer interrupt so that it's still invoked 
18.2 times/sec.

I originally did this using protected mode interrupts which worked fine,
but
it seemed slightly more expensive than when previously working in real
mode
under Borland. So I rewrote using real mode interrupts, but this has
proved 
significantly more expensive.

Below is my joystick code. Any ideas? Even though I've only installed a
real 
mode isr, is it possible that there's still some protected mode isr
processing being done?

Cheers,
Paul.

/***************************************************************************/
/*
Includes                                                               
*/
/***************************************************************************/

#include <stdio.h>
#include <dpmi.h>
#include <sys/nearptr.h>
#include <sys/movedata.h>

/***************************************************************************/
/*
Constants                                                              
*/
/***************************************************************************/

#define TIMER_VECTOR (0x08)
#define FILL (0x00)

/***************************************************************************/
/* Global
Variables                                                        */
/***************************************************************************/

int* joystickX;
int* joystickY;
int* joystickButtons;

/***************************************************************************/
/* Local
Variables                                                         */
/***************************************************************************/

static __dpmi_raddr oldVector;
static __dpmi_raddr newVector;
static int joystickIsrSelector;

/***************************************************************************/
/*                                                                        
*/
/*
joystickIsr                                                            
*/
/*                                                                        
*/
/* This code is copied into dos memory and configured as the real
mode     */
/* timer isr. The bytes marked FILL are overwritten during
installation:   */
/* the 2 bytes at offset 0x05 are set to the dos memory segment
(where     */
/* this code is located), the 4 bytes at offset 0x72 are set to
the        */
/* segment:offset of the old real mode timer
isr.                          */
/*                                                                        
*/
/***************************************************************************/

static char joystickIsr[] =
{
    /* 0000 */ 0x50,                   /* push ax */
    /* 0001 */ 0x52,                   /* push dx */
    /* 0002 */ 0x1E,                   /* push ds */
    /* 0003 */ 0x55,                   /* push bp */
    /* 0004 */ 0xBD, FILL, FILL,       /* mov bp,SEGMENT */
    /* 0007 */ 0x8E, 0xDD,             /* mov ds,bp */
    /* 0009 */ 0xFF, 0x06, 0x70, 0x00, /* inc word ptr TIMECOUNT */
    /* 000D */ 0x81, 0x3E,             /* cmp word ptr TIMECOUNT,0x0155
*/
	       0x70, 0x00, 0x55, 0x01,
    /* 0013 */ 0x75, 0x10,             /* jne L1 */
    /* 0015 */ 0xC7, 0x06,             /* mov word ptr TIMECOUNT,0x0000
*/
	       0x70, 0x00, 0x00, 0x00,
    /* 001B */ 0x9C,                   /* pushf */
    /* 001C */ 0xFF, 0x1E, 0x72, 0x00, /* call dword ptr OLDHANDLER */
    /* 0020 */ 0x5D,                   /* pop bp */
    /* 0021 */ 0x1F,                   /* pop ds */
    /* 0022 */ 0x5A,                   /* pop dx */
    /* 0023 */ 0x58,                   /* pop ax */
    /* 0024 */ 0xCF,                   /* iret */
    /* 0025 */ 0xBA, 0x01, 0x02,       /* L1: mov dx,0x0201 */
    /* 0028 */ 0xEC,                   /* in al,dx */
    /* 0029 */ 0xA8, 0x03,             /* test al,0x03 */
    /* 002B */ 0x75, 0x2A,             /* jne L2 */
    /* 002D */ 0xF6, 0xD0,             /* not al */
    /* 002F */ 0x24, 0x30,             /* and al,0x30 */
    /* 0031 */ 0xC0, 0xE8, 0x04,       /* shr al,0x04 */
    /* 0034 */ 0xA2, 0x80, 0x00,       /* mov byte ptr JOYBUTTONS,al */
    /* 0037 */ 0xA0, 0x76, 0x00,       /* mov al,byte ptr XCOUNT */
    /* 003A */ 0xA2, 0x78, 0x00,       /* mov byte ptr JOYX,al */
    /* 003D */ 0xA0, 0x77, 0x00,       /* mov al,byte ptr YCOUNT */
    /* 0040 */ 0xA2, 0x7C, 0x00,       /* mov byte ptr JOYY,al */
    /* 0043 */ 0xC6, 0x06,             /* mov byte ptr XCOUNT,0x00 */
	       0x76, 0x00, 0x00,
    /* 0048 */ 0xC6, 0x06,             /* mov byte ptr YCOUNT,0x00 */
	       0x77, 0x00, 0x00,
    /* 004D */ 0xEE,                   /* out dx,al */
    /* 004E */ 0xB0, 0x20,             /* mov al,0x20 */
    /* 0050 */ 0xE6, 0x20,             /* out 0x20,al */
    /* 0052 */ 0x5D,                   /* pop bp */
    /* 0053 */ 0x1F,                   /* pop ds */
    /* 0054 */ 0x5A,                   /* pop dx */
    /* 0055 */ 0x58,                   /* pop ax */
    /* 0056 */ 0xCF,                   /* iret */
    /* 0057 */ 0xA8, 0x01,             /* L2: test al,0x01 */
    /* 0059 */ 0x74, 0x04,             /* je L3 */
    /* 005B */ 0xFE, 0x06, 0x76, 0x00, /* inc byte ptr XCOUNT */
    /* 005F */ 0xA8, 0x02,             /* L3: test al,0x02 */
    /* 0061 */ 0x74, 0x04,             /* je L4 */
    /* 0063 */ 0xFE, 0x06, 0x77, 0x00, /* inc byte ptr YCOUNT */
    /* 0067 */ 0xB0, 0x20,             /* L4: mov al,0x20 */
    /* 0069 */ 0xE6, 0x20,             /* out 0x20,al */
    /* 006B */ 0x5D,                   /* pop bp */
    /* 006C */ 0x1F,                   /* pop ds */
    /* 006D */ 0x5A,                   /* pop dx */
    /* 006E */ 0x58,                   /* pop ax */
    /* 006F */ 0xCF,                   /* iret */
    /* 0070 */ 0x00, 0x00,             /* TIMECOUNT: dc.w 0x0000 */
    /* 0072 */ FILL, FILL,             /* OLDHANDLER(offset): ds.w 1 */
    /* 0074 */ FILL, FILL,             /* OLDHANDLER(segment): ds.w 1 */
    /* 0076 */ 0x00,                   /* XCOUNT: dc.b 0x00 */
    /* 0077 */ 0x00,                   /* YCOUNT: dc.b 0x00 */
    /* 0078 */ 0x04, 0x00, 0x00, 0x00, /* JOYX: dc.l 0x00000004 */
    /* 007C */ 0x04, 0x00, 0x00, 0x00, /* JOYY: dc.l 0x00000004 */
    /* 0080 */ 0x00, 0x00, 0x00, 0x00  /* JOYBUTTONS: dc.l 0x00000000 */
};

/***************************************************************************/
/*                                                                        
*/
/*
installJoystick                                                        
*/
/*                                                                        
*/
/* Install joystickHandler and increase interrupt
frequency.               */
/*                                                                        
*/
/***************************************************************************/

void installJoystick (void)
{
    int numParagraphs;
    int segment;

    /* get current real mode timer isr */
    if (__dpmi_get_real_mode_interrupt_vector (TIMER_VECTOR,
&oldVector))
	printf ("Error: unable to get real mode interrupt\n");

    /* determine number of paragraphs for new isr */
    numParagraphs = (sizeof (joystickIsr) + 15) >> 4;

    /* allocate dos memory for new isr */
    segment = __dpmi_allocate_dos_memory (numParagraphs,
					  &joystickIsrSelector);

    if (segment == -1)
	printf ("Error: unable to allocate dos memory\n");

    /* set new isr's segment and old vector address */
    *(short*)(joystickIsr + 0x05) = segment;
    *(short*)(joystickIsr + 0x72) = oldVector.offset16;
    *(short*)(joystickIsr + 0x74) = oldVector.segment;

    /* copy new isr into dos memory */
    dosmemput (joystickIsr, sizeof (joystickIsr), segment << 4);

    /* configure new isr vector address */
    newVector.offset16 = 0x0000;
    newVector.segment = segment;

    /* set new real mode timer isr */
    if (__dpmi_set_real_mode_interrupt_vector (TIMER_VECTOR,
&newVector))
	printf ("Error: unable to set real mode interrupt\n");

    /* set counter 0 to 6206.2 interrupts/sec */
    asm ("cli");
    asm ("movb $0x36,%al");
    asm ("outb %al,$0x43");
    asm ("movb $0xC0,%al");
    asm ("outb %al,$0x40");
    asm ("movb $0x00,%al");
    asm ("outb %al,$0x40");
    asm ("sti");

    /* configure protected mode pointers to real mode data (must have 
       previously enabled near pointers) - i.e. joystickX points to
JOYX, 
       joystickY to JOYY and joystickButtons to JOYBUTTONS */
    joystickX = (int*)(__djgpp_conventional_base + (segment << 4) +
0x78);
    joystickY = (int*)(__djgpp_conventional_base + (segment << 4) +
0x7C);
    joystickButtons = (int*)(__djgpp_conventional_base + (segment << 4)
+ 0x80);
}

/***************************************************************************/
/*                                                                        
*/
/*
removeJoystick                                                         
*/
/*                                                                        
*/
/* Restore interrupt frequency and old interrupt
handler.                  */
/*                                                                        
*/
/***************************************************************************/

void removeJoystick (void)
{
    /* set counter 0 to 18.2 interrupts/sec */
    asm ("cli");
    asm ("movb $0x36,%al");
    asm ("outb %al,$0x43");
    asm ("movb $0x00,%al");
    asm ("outb %al,$0x40");
    asm ("movb $0x00,%al");
    asm ("outb %al,$0x40");
    asm ("sti");

    /* restore original real mode timer isr */
    if (__dpmi_set_real_mode_interrupt_vector (TIMER_VECTOR,
&oldVector))
	printf ("Error: unable to set real mode interrupt\n");

    /* free dos memory allocated for new isr */
    if (__dpmi_free_dos_memory (joystickIsrSelector))
	printf ("Error: unable to free dos memory\n");
}

/***************************************************************************/
/*                                                                        
*/
/* This only shows how the above are used - you can't judge
performance    */
/* from
this!                                                              */
/*                                                                        
*/
/***************************************************************************/

void main (void)
{
    if (!__djgpp_nearptr_enable ())
	printf ("Error: unable to enable near pointers\n");

    installJoystick ();

    /* while no buttons pressed */
    while (!*joystickButtons)
    {
	printf ("x = %x y = %x\n", *joystickX, *joystickY);
    }

    removeJoystick ();
}

- Raw text -


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