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 #include #include #include #include #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; }