Date: Thu, 09 Mar 1995 16:23:32 EST From: THE MASKED PROGRAMMER To: djgpp AT sun DOT soe DOT clarkson DOT edu Cc: badcoe AT bsa DOT bristol DOT ac DOT uk Subject: May I interrupt ? Hi, A have a problem with the following test program. It supposed to demonstrate increasing the clock-tick and redirecting int 8 into a routine that only calls the original routine when necessary. ** 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); tics -= 0x10000; } } 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 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" puts("Hi"); count = 0; while(count < 50) { ## Line "Y" if (my_tics > oldtics) { 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