www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1995/08/04/14:20:28

Date: Fri, 4 Aug 1995 13:19:47 -0400
From: Andrew Szymkowiak <aes AT xtelab DOT gsfc DOT nasa DOT gov>
To: djgpp AT sun DOT soe DOT clarkson DOT edu
Subject: please help (yet another) newbie with timer interrupts

Dear DJGPP gurus,
   I am making my first serious foray into using DJGPP (1.12m4 for
those keeping track) and am having trouble converting a program
that was running under the Intel Codebuilder compiler.  I have
made some attempts to figure this out with the FAQ, the mail
archive, and looking at examples, but apologize anyway for
what will probably be well known to all the cognoscenti.
   The following fragment (mis)uses a DOS function which performs 
an "event_wait" function; usually, after the specifed time the
flag is set.  This will not happen in my example, since I have
replaced the interrupt at 0x70.  During my interrupt, the "clear_int" 
routine reprograms the real-time clock chip.
   My machine hangs when I execute this code (either manually or
stepping through it with gdb or ladybug).
 
   Here are a few things that I am particularly uncertain about:

Does "clear_in.s" need more/different pro and post-log ops (i.e. register
saving and restoring, stack adjusting, etc)?

Where do I need enable/disable calls? (Also, why does the sblaster
example code #define replacements for these?  Is that important?)

Thanks,
   Andy S.

#include <bios.h>
#include <malloc.h>
#include <dos.h>
#include <stdarg.h>
#include <pc.h>
#include <dpmi.h>
#include <go32.h>

int wait_flag = 0;

static _go32_dpmi_registers dinregs;

void event_wait(void);

int int_cntr = 0;

static _go32_dpmi_seginfo rm_si;
static _go32_dpmi_seginfo oldirq_rm;
static _go32_dpmi_registers rm_regs;
static _go32_dpmi_seginfo pm_si;
static _go32_dpmi_seginfo oldirq_pm;

void int8_isr(void)
{
	int_cntr++;
	clear_int();
	enable();
}

#define TIM_IRQ 0x70

void install_tim_vect(void)
{
    int ret;

    disable();

    _go32_dpmi_get_real_mode_interrupt_vector( TIM_IRQ, &oldirq_rm);
    rm_si.pm_offset = (int) int8_isr;
    ret = _go32_dpmi_allocate_real_mode_callback_iret(
	     &rm_si, &rm_regs);
    if ( ret != 0 ) printf(" cannot alloc real mode callback\n");
    ret = _go32_dpmi_set_real_mode_interrupt_vector( TIM_IRQ, &rm_si);
    if ( ret != 0 ) printf(" cannot set real mode vector\n");

    _go32_dpmi_get_protected_mode_interrupt_vector( TIM_IRQ, &oldirq_pm);
    pm_si.pm_offset = (int) int8_isr;
    ret = _go32_dpmi_allocate_iret_wrapper(
	     &pm_si);
    if ( ret != 0 ) printf(" cannot alloc iret wrapper\n");
    ret = _go32_dpmi_set_protected_mode_interrupt_vector( 
	TIM_IRQ, &pm_si);
    if ( ret != 0 ) printf(" cannot set prot mode vector\n");
    enable();
    event_wait();
}

void event_wait(void)
{
    dinregs.x.ax = 0x8300;   /* Event wait with es:bx = pointer to user flag */
    dinregs.x.cx = 0x0;      /*                 cx,dx = Number of microseconds */
    dinregs.x.dx = 0x3d1;

    dinregs.x.es = 0L;
    dinregs.x.bx = 0L;

    /* Execute int 15 interrupt */
    _go32_dpmi_simulate_int( 0x15, &dinregs);
}

/*;======================================================================
; io.asm -- assembly language i/o subroutines
; attempt by AES to convert to AT&T form for GAS
;*/
	.data
	.text
	.align 4
        .globl	_clear_int

_clear_int:

	pushl %eax

        mov     $0ch,%al
        out     %al,$70h

	nop
	nop
	nop
	nop
	nop
        in      $71h,%al

        mov     $20h,%al
        out     %al,$0a0h
        out     %al,$20h
	popl %eax

        ret


- Raw text -


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