delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1994/10/11/21:55:22

From: dtauritz AT WI DOT LeidenUniv DOT NL (D.R.Tauritz)
Organization: Leiden University,
Dept. of Mathematics & Computer Science,
The Netherlands
Subject: Segmentation violations
To: djgpp AT sun DOT soe DOT clarkson DOT edu
Date: Tue, 11 Oct 1994 22:03:41 +0100 (MET)

Thanks for pointing out to me the need for a real mode interrupt handler
because of real mode DOS & BIOS calls. Thanks to Eli Zaretskii for finding
the bug in my program, I hadn't enabled the PICs, though I did send EOIs for
both of them in my interrupt routine. The reason for this is simple, I didn't
need to do this in the original assembly code because the DOS extender I was
using did this for me.

Now my interrupt routine is called... and the more subtle bugs arise :-(
Every time the user presses a key an interrupt is generated. The interrupt
routine simply increases a counter. On return of the interrupt the value of
the counter is displayed on the screen. The output should obviously be:
  tics=0
  tics=1
  tics=2
  tics=3
  etc.
Alas, the output is for example:
  tics=0
  tics=0
  tics=2
  tics=4
  tics=5
  tics=7
  tics=8
  tics=9
  tics=10
  ...
  tics=406
  tics=408
  Unsupported
  INT 0x0d
  tics=410
  Segmentation violation in pointer 0xf000a001 at a00:1
  eax=00003093 ebx=00000000 ecx=0000019e edx=00000020 esi=0002a61c
  edi=00004150 ebp=00000000 esp=12102cbc cs=a00 ds=37f es=2cbc fs=12c2
  gs=2cbc ss=ca57 cr2=0000a001
  Call frame traceback EIPs:
    0x00000001

I have appended my program at the end of this message. I would really
appreciate it if anyone could give me a hint how to solve this one.

The best of wishes and hoping to hear from you soon,

Daniel

-----------------------------------------------------------------------------
| Daniel R. Tauritz                            | Maintainer of the          |
| E-mail: dtauritz AT wi DOT leidenuniv DOT nl            |   Aria FAQ                 |
| Department of Mathematics & Computer Science |   Aria Internet Department |
| University of Leiden                         |   Aria Support List        |
| The Netherlands                              |   Leiden Audio Archives    |
-----------------------------------------------------------------------------
|     The Aria Internet Department: ftp.wi.leidenuniv.nl:pub/audio/aria     |
-----------------------------------------------------------------------------



#include <stdio.h>
#include <pc.h>
#include <dos.h>
#include <dpmi.h>
#include <go32.h>

#define BASEPORT     0x290
#define MY_INTERRUPT 0x72
#define MY_IRQ       10

_go32_dpmi_seginfo old_handler, new_handler, oldirq_rm, rm;
_go32_dpmi_registers rm_regs;
volatile int tics;

void aria_putmem (int address, int word)
{
  outportw (BASEPORT+4, address);
  outportw (BASEPORT+6, word);
  return;
}

int aria_getmem (int address)
{
  int word;
  outportw (BASEPORT+4, address);
  word=inportw (BASEPORT+6);
  return word;
}

void aria_sendcmd (unsigned command)
{
  unsigned i=65535;
  while (i--)
  {
    if (!(inportw(BASEPORT+2) & 0x8000))
    {
      outportw (BASEPORT, command);
      return;
    }
  }
  printf ("time out\n");
  exit(1);
}

void aria_init()
{
  int ready=0;

  outportw (BASEPORT+2,0xc8);          /* Aria init */
  aria_putmem (0x6102,0);              /* Clear task init flag */

  /* Aria DSP Init */
  disable();
  aria_sendcmd (0x00);
  aria_sendcmd (0x00);
  aria_sendcmd (0x00);
  aria_sendcmd (0x00);
  aria_sendcmd (0xffff);
  enable();

  /* Wait for Aria DSP init to complete */
  while (ready != 1)
  {
    outportw (BASEPORT+4, 0x6102);
    ready = inportw (BASEPORT+6);
  }

  outportw (BASEPORT+2,0xca);           /* Complete Aria init */

  return;
}

void aria_irqhandler()
{
  disable();
  tics++;
  outportb (0xa0,0x20);   /* secondary controller EOI */
  outportb (0x20,0x20);   /* primary controller EOI   */
  enable();
  return;
}

void aria_install_interrupt_handler ()
{
  /* Install protected mode interrupt handler */
  disable();
  _go32_dpmi_get_protected_mode_interrupt_vector (MY_INTERRUPT,
                                                            &old_handler);
  new_handler.pm_offset = (int)aria_irqhandler;
  new_handler.pm_selector = _go32_my_cs();
  if((_go32_dpmi_chain_protected_mode_interrupt_vector(MY_INTERRUPT,
                                                            &new_handler))!=0)
  {
    printf("cannot chain protected mode interrupt\n");
    exit(1);
  }
  enable();

  /* Install real mode interrupt handler */
  rm.pm_offset = (int)aria_irqhandler;
  if ((_go32_dpmi_allocate_real_mode_callback_iret(&rm, &rm_regs))!=0)
  {
    printf("cannot allocate real mode callback\n");
    exit(1);
  }
  disable();
  _go32_dpmi_get_real_mode_interrupt_vector(MY_INTERRUPT, &oldirq_rm);
  _go32_dpmi_set_real_mode_interrupt_vector(MY_INTERRUPT, &rm);
  enable();

  /* Enable interrupts via Aria's IRQ */
  outportw (0xA1,inportb(0xA1) & ~(1<<(MY_IRQ-8)));

  return;
}

void aria_generate_interrupt()
{
  /* Generate interrupt via IRQ 10 (software interrupt 0x72) */
  disable();
  aria_sendcmd (0xa);
  aria_sendcmd (0xffff);
  enable();

  return;
}

void aria_release_interrupt_handler ()
{
  /* Disable interrupts via Aria's IRQ */
  outportw (0xA1,inportb(0xA1) | (1<<(MY_IRQ-8)));

  /* Restore original protected mode interrupt handler */
  disable();
  _go32_dpmi_set_protected_mode_interrupt_vector(MY_INTERRUPT,&old_handler);
  enable();

  /* Remove our real mode interrupt handler */
  disable();
  _go32_dpmi_set_real_mode_interrupt_vector(MY_INTERRUPT, &oldirq_rm);
  _go32_dpmi_free_real_mode_callback(&rm);
  enable();

  return;
}

void aria_reset ()
{
  outportw (BASEPORT+2,0x40);
  return;
}

int main()
{
  char key=' ';

  aria_init();
  aria_install_interrupt_handler();

  while (key!='q')
  {
    printf ("tics=%d\n",tics);
    key=getkey();

    aria_generate_interrupt();
  }

  aria_release_interrupt_handler();
  aria_reset();
  return 0;
}

- Raw text -


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