Date: Fri, 4 Aug 1995 13:19:47 -0400 From: Andrew Szymkowiak 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 #include #include #include #include #include #include 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