Mail Archives: djgpp/1994/10/11/21:55:22
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 -