Click here to Skip to main content
15,899,314 members
Home / Discussions / C / C++ / MFC
   

C / C++ / MFC

 
GeneralRe: Link Error Pin
BrockVnm23-Jan-04 5:09
BrockVnm23-Jan-04 5:09 
Generalmicroseconds Pin
lpRomang23-Jan-04 2:09
lpRomang23-Jan-04 2:09 
GeneralRe: microseconds Pin
фил23-Jan-04 2:30
фил23-Jan-04 2:30 
GeneralRe: microseconds Pin
lpRomang23-Jan-04 3:54
lpRomang23-Jan-04 3:54 
GeneralRe: microseconds Pin
RChin23-Jan-04 3:53
RChin23-Jan-04 3:53 
GeneralRe: microseconds Pin
dknoble23-Jan-04 6:48
dknoble23-Jan-04 6:48 
GeneralRe: microseconds Pin
Marcello25-Jan-04 10:50
Marcello25-Jan-04 10:50 
GeneralRe: microseconds Pin
dknoble26-Jan-04 2:28
dknoble26-Jan-04 2:28 
Since there appears to be no email, but only public and private postings, I'll post the source code here. The routines in 'interpts.h' are self-explanitory: install interrupts, including the clock-tick interrupt, which occurs every 18.2ms. The functions clock_tick is chained to this interrupt, and merely counts elapsed time, whose origin happens to be the installation of interrupts, but could be anything.

The routine mtime() happens to be used within an irq4 routine -- I want to know the time when a serial event occurs. It should be unnecessary to have mtime() occuring within an interrupt. Note that irq4 has lower priority than irq0.

A good (old) book on DOS programming might also help.

copy an paste:

/*
mtime.h
Purpose: get time with 100 microsecond resolution.
The resolution could be microsecond, but is 100 microsec because the
time is being stored as integers in a huge array.
*/

#if !defined(MTIME_DEFINED)
// convert mtime struct to seconds as double
#define MTIME_TICKS_PER_SEC 10000.0
#define mtsec2sec(x) ((double)(x) / MTIME_TICKS_PER_SEC)
typedef unsigned long mtime;
#define MTIME_DEFINED

// defs for clock_tick()
#define CLOCK_FREQUENCY 1193180UL // frequency of 8253 timer
#define CLOCKTICKS_PER_TICK 65536UL // clock ticks before interrupt occurs
#define CLOCK_TICKS_PER_SEC\
((double) CLOCK_FREQUENCY / CLOCKTICKS_PER_TICK)
#define SECONDS_PER_CLOCK_TICK\
((double) CLOCKTICKS_PER_TICK / CLOCK_FREQUENCY)
#endif

extern volatile unsigned long tick_time;

extern const double seconds_per_tick,
tenth_milliseconds_per_tick;
extern int interrupts_installed; // true when interrupts are installed

// current time from tick time - accurate to 50 msec.
#define current_tick_time() (tick_time * seconds_per_tick) // clock in seconds.

mtime msec10_time(void); // get time in 1/10 msec
int clock_tick(void); // accumulate clock_ticks on int 08
// eof

//***********************

/*
mtime.c
Purpose: determine time from tick_time and 8253 timer. Time is obtained
in 100 microsecond (tenth millisecond) units.

Also has interrupt routine which updates clock tick at each
bios clock-tick (18.2 times per second) - IRQ0.

Method: tick_time (from interpts.c) is updated with every bios tick, as
part of timer interrupt IRQ0. msec10_time() takes that tick
count, and the timer value (which is microsecond resolution),
and combines them for accurate time. If the timer tick, as
determined by the IRQ0 routine which increments it, is different
before and after the input instructions, then the input will be
done a second time (and won't infringe on another timer tick
increment). Note that tick_time *must* be declared volatile, or
the compiler will not retrieve it again at the end of the loop,
but will rather "optimize" this part away.

*NOTE* Floating point calculation used. The computer *must*
have a math coprocessor, and the software must be compiled
*without* the emulator option, since the emulator uses
software interrupts, and the calling program could be
doing a fp calc when this routine is called.

*NOTE* time will overflow after 5 days.

Portions learned from Mark Piggott, Compuserve 100316,454
Thanks Mark.
*/

#include <conio.h>
#include "interpts.h"
#include "mtime.h"

#define TIMER_CTL_PORT 0x43 // Mode Control Register
#define TIMER0_PORT 0x40 // Counter 0
//#define TIMER_CFG 0x36 // Timer 0, Write LSB then MSB, Mode 3, Binary
#define TIMER_READ 0x00 // Timer 0, Latch, Mode 3, Binary
// Timer countdown frequency / 10000
#define TFREQ_10000 (CLOCK_FREQUENCY / MTIME_TICKS_PER_SEC)

// static int is_mode2 = 0; // true after first call - not used for now
volatile unsigned long tick_time = 0; // clock ticks since installation
const double seconds_per_tick = 1.0 * SECONDS_PER_CLOCK_TICK, // cf interpts.h
tenth_milliseconds_per_tick = MTIME_TICKS_PER_SEC * SECONDS_PER_CLOCK_TICK;

#pragma intrinsic(inp, outp)
#pragma check_stack(off) // can't use stack check on interrupt routines
//#pragma optimize ("", off)
//======================================================================

mtime msec10_time(void)
{
static unsigned int timer_count, // combined 8253 register value
pending0; // true if irq0 pending
static unsigned long ticks; // copy of tick_count on entry
static unsigned char lsb, msb; // lsb and msb of timer count

/* Obtain timer values. Note, this routine is used within an IRQ4 routine,
whose priority is less than IRQ0. This, tick_time may be incremented
while the routine is executing. Confirm whether or not this happens
*/

// Obtain ticks and timer values. If IRQ0 interrupts (tick_time change),
// then do it again.
// do
{ ticks = tick_time; // bios time from IRQ0 add_on (below)
(void) outp(TIMER_CTL_PORT, TIMER_READ); // Counter 0, Latch, Mode 3, Bin
lsb = (unsigned char) inp(TIMER0_PORT); // lsb
msb = (unsigned char) inp(TIMER0_PORT); // msb
// since ints disabled, is irq0 pending?
(void) outp(ADDR_8259_OCW3, IRR_REGISTER);
pending0 = inp(ADDR_8259_OCW3) & IRQ0_PENDING;
}// while (ticks != tick_time);

// timer is count down - invert to count up
timer_count = (msb ^ 0xff) << 8 | (lsb ^ 0xff);

if (timer_count < 0x8000 && pending0) // if irq0 is pending, fix ticks
ticks++;

return (mtime)
(ticks * tenth_milliseconds_per_tick + timer_count / TFREQ_10000);
}
//=========================================================================

int clock_tick(void)
//Interrupt routine for IRQ0 - timer interrupt
{
tick_time++;
return 0;
}
//==========================================================================
// eof
//****************************

/*
interpts.h
Purpose: prepare for, and clean up after, installing an interrupt drive
for COM1 for the appleton photometer.
Method: Prepare for the interupt by installing the interrupt driver,
and then masking the 8254 for IRQ4, and enabling interrupts.
This interrupt is *not* chained to the previous one.
Clean up consists of turning off the mask for IRQ4, and
removing the interupt driver, replacing with the original.
*/

// (various com port defines removed here.)
#define IRQ0_PENDING 0x01 // is irq0 pending?
// data output to PIC:
#define IRR_REGISTER 0x0a // interrupt req register (pending ints)
#define ISR_REGISTER 0x0b // In-service register (pending or being served)
#define EOI 0x20 // EOI code to end this interrupt

void interrupts_install(int allo_light); // install interrupt
void interrupts_free(void); // free interrupt
void com_on_off(int on); // turn com on and off
// eof
//***************
//end-of-posting



Dave Knoble
GeneralRe: microseconds Pin
Marcello26-Jan-04 6:08
Marcello26-Jan-04 6:08 
GeneralOn_exit and signal Pin
Anonymous23-Jan-04 1:34
Anonymous23-Jan-04 1:34 
GeneralRichEdit Pin
edwinak23-Jan-04 1:24
edwinak23-Jan-04 1:24 
GeneralRe: RichEdit Pin
CodeBrain23-Jan-04 1:35
CodeBrain23-Jan-04 1:35 
GeneralRe: RichEdit Pin
edwinak23-Jan-04 1:57
edwinak23-Jan-04 1:57 
GeneralVB and C strings Pin
Tzoockee23-Jan-04 0:51
Tzoockee23-Jan-04 0:51 
GeneralRe: VB and C strings Pin
фил23-Jan-04 2:29
фил23-Jan-04 2:29 
QuestionHow many Serial Ports do I have? Pin
Dean Warren23-Jan-04 0:50
Dean Warren23-Jan-04 0:50 
AnswerRe: How many Serial Ports do I have? Pin
TFrancis23-Jan-04 5:26
TFrancis23-Jan-04 5:26 
AnswerRe: How many Serial Ports do I have? Pin
Antti Keskinen23-Jan-04 5:27
Antti Keskinen23-Jan-04 5:27 
GeneralMicrosoft Visual C ++ for Windows64-bit (no PreRelease) Pin
vladimirh23-Jan-04 0:39
vladimirh23-Jan-04 0:39 
GeneralRe: Microsoft Visual C ++ for Windows64-bit (no PreRelease) Pin
Mike Dimmick23-Jan-04 0:47
Mike Dimmick23-Jan-04 0:47 
GeneralRe: Microsoft Visual C ++ for Windows64-bit (no PreRelease) Pin
hvladimir23-Jan-04 2:34
susshvladimir23-Jan-04 2:34 
GeneralPKZIP error Pin
JensB22-Jan-04 23:38
JensB22-Jan-04 23:38 
GeneralRe: PKZIP error Pin
Steve S23-Jan-04 0:23
Steve S23-Jan-04 0:23 
GeneralRe: PKZIP error Pin
JensB23-Jan-04 1:25
JensB23-Jan-04 1:25 
GeneralRe: PKZIP error Pin
Steve S23-Jan-04 6:40
Steve S23-Jan-04 6:40 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.