Date: Thu, 9 Mar 1995 13:14:49 +0500 From: ld AT netrix DOT com To: badcoe AT bsa DOT bris DOT ac DOT uk Subject: Re: May I interrupt ? Cc: djgpp AT sun DOT soe DOT clarkson DOT edu My comments begin with ***. Hope they help, Long. > ** CODE BEGINS ************* > > #include > #include > #include > #include > #include > #include > > #define CLOCK_RATE 1193181 > > volatile unsigned int tics = 0; > volatile unsigned int my_tics = 0; > unsigned int Clock_Count=0x10000, CCL=0, CCH=0; > > _go32_dpmi_seginfo old_pm_handler, old_rm_handler; > _go32_dpmi_seginfo new_pm_handler, new_rm_handler; > _go32_dpmi_registers dummy, old; > > void set_count_one(unsigned int freq) { > Clock_Count = CLOCK_RATE / freq; > printf("f:%i CC:%i\n", freq, Clock_Count); > fflush(stdout); > ## Section "J" > /* outportb(0x43, 0x34); ## this is the bit that changes > outportb(0x40, (CCL = Clock_Count & 0xff)); ## the rate of the PIT the > outportb(0x40, (CCH = Clock_Count >> 8));*/ ## program crashes whether this > ## is commented or not. > printf("CCL:%i CCH:%i\n", CCL, CCH); > fflush(stdout); > } > > void cleanup() { > outportb(0x43, 0x34); > outportb(0x40, 0x00); > outportb(0x40, 0x00); > > _go32_dpmi_set_protected_mode_interrupt_vector(8, &old_pm_handler); > _go32_dpmi_set_real_mode_interrupt_vector(8, &old_rm_handler); > puts("CleanUp"); > } > > void timer_handler() { > my_tics++; > tics += Clock_Count; > if (tics >= 0x10000) { > _go32_dpmi_simulate_fcall_iret(&old); *** When you finish this call, old.x.cs, old.x.ip, old.x.sp, old.x.ss, old.x.bp *** are changed, and the next time this you make this call, something ought to *** break. > tics -= 0x10000; > } *** The Interrupt Controller does not recieve an ACK here, so it will wait *** for one (which nobody seems to care to send...:-<) > } > > int main() { > int oldtics = 0, count = 0, speed; > > _go32_dpmi_get_protected_mode_interrupt_vector(8, &old_pm_handler); > _go32_dpmi_get_real_mode_interrupt_vector(8, &old_rm_handler); > old.x.cs = old_rm_handler.rm_segment; > old.x.ip = old_rm_handler.rm_offset; > old.x.ss = old.x.sp = 0; > > printf("%x %x\n", old_pm_handler.pm_offset, ## This is odd too, pm_handler > old_rm_handler.rm_offset); ## seems to have an offset=0 *** No, pm_handler has a value of (If I remember right) a0:00000000 because *** it is _NOT_ a interrupt gate, but a task gate. That's why the program will *** crash if you do _go32_dpmi_set_..._p..._vector (8, &old_pm_handler) and *** keep running the program. > atexit(cleanup); > new_pm_handler.pm_offset = (int)timer_handler; > new_pm_handler.pm_selector = _go32_my_cs(); > new_rm_handler.pm_offset = (int)timer_handler; > new_rm_handler.pm_selector = _go32_my_cs(); > _go32_dpmi_allocate_real_mode_callback_iret(&new_rm_handler, &dummy); > _go32_dpmi_allocate_iret_wrapper(&new_pm_handler); > _go32_dpmi_set_protected_mode_interrupt_vector(8, &new_pm_handler); > _go32_dpmi_set_real_mode_interrupt_vector(8, &new_rm_handler); > > puts("Entering"); > fflush(stdout); > > for(speed = 30; speed < 121; speed *= 2) { > set_count_one(speed); ## Line "X" *** You should clear the interrupt enable flag before programming the chip, *** or change the IDT. (Applicaple inside set_count_one and the code above.) > puts("Hi"); > count = 0; > while(count < 50) { > ## Line "Y" > if (my_tics > oldtics) { *** This is due to the interrupt handler (see above.) After it got hit, it NEVER *** pass control back. > oldtics++; > count++; > printf("%i %i %li\n", my_tics, tics, time(0)); > fflush(stdout); > } > } > } > > return 0; > } > > > ** CODE ENDS ********************* > > The problem is as follows: > > If line "X" is commented out, the program runs as expected (with my routine > and the original clock running at 18.3 times per second. > > If line "X" is present then the program seems to hang. A print at line "Y" > gets printed but the print inside the "if() {}" doesn't (I did have some > fflush(stdout)'s in there as well). > > This happens whether or not section "J" is present. > > I read in a FAQ document, that the return values from > _go32_dpmi_get_protected_mode_interrupt_vector were corrupt and this does > seem to be the case. Is their any truth in that ? Is it related to my > problem ? > > Any help appreciated, I have looked in the FAQ and didn't see any relevant > help. > > Badders > > >