delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1996/02/01/14:03:10

From: "James T. Sweeten Jr." <sweeten AT belgarath DOT nwscc DOT sea06 DOT navy DOT mil>
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 <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 -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019