Mail Archives: djgpp/1996/02/01/14:03:10
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 <conio.h>
#include <stdio.h>
#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 <dos.h>
#include <dpmi.h>
#include <pc.h>
#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);
}
}
- Raw text -