delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1995/05/30/16:29:51

Date: Tue, 30 May 95 13:08 MDT
From: mat AT ardi DOT com (Mat Hostetter)
To: djgpp AT sun DOT soe DOT clarkson DOT edu
Subject: Re: Manually calling iret functions
References: <9505301726 DOT AA00437 AT jasmine>

>  1. A protected mode handler, which does the following:
>      a. Increases & checks the tick count.
>      b. Use _go32_dpmi... to call the old interrupt.
>      c. Do whatever the ISR is supposed to do.

Back in our pre-DPMI days, Executor used to reprogram the clock and
forward every 18.2 Hz.  We have since abandoned this approach, and now
we patch into the 1024 Hz clock.  In the old days our handler would
"ljmp" down the PM interrupt chain when it wanted to forward the tick,
otherwise it would issue an "end-of-interrupt" command to the timer
controller (our docs are shaky on that, though).

Most approaches will eat flaming death if your interrupt handler gets
paged out, which is a big problem for any djgpp app that tries to use
interrupts.  These days all of Executor's interrupt handlers are
written in assembly.  They and their data are carefully locked down
with the appropriate DPMI call so they can't get paged out.

Here are some relevant code snippets you might (or might not) find
useful.

-Mat


/* This reprograms the clock to a specified Hz, which need not be an int. */
#define REPROGRAM_TIMER_0(ticks_per_sec)				  \
asm volatile ("movb $0x36,%%al\n\t"					  \
	      "outb %%al,$0x43\n\t"					  \
	      "jmp 1f\n"						  \
	      "1:\tjmp 1f\n"						  \
	      "1:\tjmp 1f\n"						  \
	      "1:\tmovb %0,%%al\n\t"					  \
	      "outb %%al,$0x40\n\t"					  \
	      "jmp 1f\n"						  \
	      "1:\tjmp 1f\n"						  \
	      "1:\tjmp 1f\n"						  \
	      "1:\tmovb %1,%%al\n\t"					  \
	      "outb %%al,$0x40\n\t" : :					  \
	      "g" ((unsigned) ((65532 / ((ticks_per_sec) / 18.2)) + 0.5)  \
		   & 0xFF),						  \
	      "g" (((unsigned) ((65532 / ((ticks_per_sec) / 18.2)) + 0.5) \
									  \
		    >> 8) & 0xFF)					  \
	      : "eax")


...
	_go32_dpmi_get_protected_mode_interrupt_vector (8, &old_handler);
...


[in the timer handler]:

	/* See if we should forward this tick to the normal 18.2 Hz handler. */
	usecs_elapsed += MICROSECONDS_PER_TICK;
	if (usecs_elapsed >= (1000000 * 10 / 182))
	  {
	    usecs_elapsed -= 1000000 * 10 / 182;
	    asm volatile ("cli\n\t"
			  "pushfl\n\t"
			  "lcall %0"
			  : : "m" (*&old_handler.pm_offset));
	  }
	else
	  {
	    /* Issue end-of-interrupt command. */
	    asm volatile ("cli\n\t"
			  "outb %b0,$0x20"
			  : : "a" (0x20));
	  }

- Raw text -


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