From: "James T. Sweeten Jr." Subject: Timer interrupts To: djgpp AT delorie DOT com Date: Thu, 1 Feb 1996 13:39:40 -0500 (EST) MIME-Version: 1.0 I have a question concerning the timer interrupt 8. What is the difference between the protected mode int8 and the real mode int 8? I need to output a value on a d/a board at specific intervals. I originally did this with borland by installing my own timer interrupt routine. I was able to get down to 100 micro second (10khz) resolution. I am trying to do the same thing using djgpp. I have read the faq and have also gotten pctime13.zip (This has milisecond resolution for djgpp). I modified the interrupt routines in pctime13.zip, (gccint8.c), to output the data to the d/a board ok but I can't get down to 100 micro second resolution. With an input value of 3000 hz I get a nice 1500 hz square wave. With a value of 4000 hz it works for a while but then locks the machine up. Any help would be appreciated. I am using 1.12m4 on a 486/66. -------------------- this is test8.c -------------------- #include #include #include "gccint8.h" void frame(void); void main(int argc, char *argv[]) { int i; int frq; unsigned long int tick_1, tick_2, elapsedtime; /* get freq in hz from command line */ if(argc != 2) exit(0); sscanf(argv[1],"%d",&frq); frame(); gotoxy(1, 3); cprintf("Press any key to quit.\n"); init8h(frq); ticks_8h = 0; getch(); quit8h(); clrscr(); gotoxy(1, 1); } void frame(void) { clrscr(); gotoxy(1, 1); cprintf("TIMER Program to output square wave(PCTIMER/IRQ0)\n"); gotoxy(1, 2); cprintf("--------------------------------------------------------------------------------\n"); gotoxy(1, 22); cprintf("--------------------------------------------------------------------------------\n"); } ---------------- this is gccint8.c ---------------- #include #include #include #include "gccint8.h" #define IRQ0 0x8 #define PIT0 0x40 #define PIT1 0x41 #define PIT2 0x42 #define PITMODE 0x43 #define PITCONST 1193180L #define PIT0DEF 18.2067597 #define KBCTRL 0x61 #define NEW8H 1 static float tick_per_ms = 0.0182068; static float ms_per_tick = 54.9246551; static float freq8h = 18.2067597; static unsigned char flag8h = 0; static _go32_dpmi_seginfo rm_old_handler, rm_new_handler, pm_old_handler, pm_new_handler; static _go32_dpmi_registers r, r1; volatile int counter_8h; volatile int counter_reset; volatile int data; volatile unsigned long int ticks_8h; void init8h(unsigned int Hz) { unsigned int pit0_set, pit0_value; if (flag8h != NEW8H) { disable(); _go32_dpmi_get_protected_mode_interrupt_vector(8, &pm_old_handler); pm_new_handler.pm_offset = (int) pm_new8h; pm_new_handler.pm_selector = _go32_my_cs(); _go32_dpmi_chain_protected_mode_interrupt_vector(8, &pm_new_handler); _go32_dpmi_get_real_mode_interrupt_vector(8, &rm_old_handler); rm_new_handler.pm_offset = (int) rm_new8h; _go32_dpmi_allocate_real_mode_callback_iret(&rm_new_handler, &r1); _go32_dpmi_set_real_mode_interrupt_vector(8, &rm_new_handler); /* outportb(PITMODE, 0x36); */ outportb(PITMODE, 0x34); pit0_value = PITCONST / Hz; pit0_set = (pit0_value & 0x00ff); outportb(PIT0, pit0_set); pit0_set = (pit0_value >> 8); outportb(PIT0, pit0_set); enable(); flag8h = NEW8H; freq8h = Hz; counter_8h = 0; counter_reset = freq8h / PIT0DEF; tick_per_ms = freq8h / 1000; ms_per_tick = 1000 / freq8h; } } void quit8h(void) { unsigned int pit0_set, pit0_value; unsigned long tick; char *cmostime; if (flag8h == NEW8H) { disable(); /* outportb(PITMODE, 0x36); */ outportb(PITMODE, 0x34); outportb(PIT0, 0x00); outportb(PIT0, 0x00); _go32_dpmi_set_real_mode_interrupt_vector(8, &rm_old_handler); _go32_dpmi_set_protected_mode_interrupt_vector(8, &pm_old_handler); _go32_dpmi_free_real_mode_callback(&rm_new_handler); enable(); } } void rm_new8h(void) { disable(); ticks_8h++; counter_8h++; if(data) outportw(0x314,0xfff0); else outportw(0x314,0x0); data^=0xffff; if (counter_8h == counter_reset) { counter_8h = 0; memset(&r, 0, sizeof(r)); r.x.cs = rm_old_handler.rm_segment; r.x.ip = rm_old_handler.rm_offset; r.x.ss = r.x.sp = 0; enable(); _go32_dpmi_simulate_fcall_iret(&r); } else { outportb(0x20, 0x20); } } void pm_new8h(void) { disable(); ticks_8h++; counter_8h++; if(data) outportw(0x314,0xfff0); else outportw(0x314,0x0); data^=0xffff; if (counter_8h == counter_reset) { counter_8h = 0; enable(); } else { outportb(0x20, 0x20); } }