/*****************************************************************
** B U S M O N . C
** Bus Monitor Hardware interface
** Reads 24-bit count of memory references each timer tick.
*/
#include <conio.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dos.h>
#ifdef GFX
#include <graphics.h>
#endif
#define MINUTES 8
#define BUFLEN (MINUTES*1092)
#define MAXTRIES 10
#define MC_CLEAR (IOport)
#define MC_READ0 (IOport)
#define MC_READ1 (IOport+1)
#define MC_READ2 (IOport+2)
void interrupt far watch_port(void);
void (interrupt far *old_timertick)(void);
volatile unsigned long MemCount[BUFLEN];
volatile int Debug[BUFLEN];
volatile int BufPtr = 0;
unsigned int IOport = 0x300;
char Command[80] = "COMMAND";
void main(int argc, char *argv[])
{
int i, ch, base;
unsigned long clip = 687000L; /* 12.5 MHz / 18.2 Hz */
char fname[80];
char *endptr;
FILE *f;
if (argc>1)
IOport = (unsigned int)strtoul(argv[1], &endptr, 0);
if (argc>2)
strcpy(Command, argv[2]);
old_timertick = _dos_getvect(0x1c);
_dos_setvect(0x1c, watch_port);
printf("MemCount Port (%x) hooked to timer tick interrupt.\n", IOport);
printf("Space allocated for roughly %d minutes worth of data.\n", MINUTES);
system(Command);
_dos_setvect(0x1c, old_timertick);
/* Throw out the first count. */
printf("A total of %d MemCounts were read.\n", BufPtr-1);
do {
printf("(S)ave, (A)verage, Plot (V)GA or (T)ext, (C)lip, (Q)uit: ");
ch = toupper(getch());
if (ch=='S') {
printf("\nEnter filename: ");
scanf("%s", fname);
f = fopen(fname, "wt");
for (i=1; i<BufPtr; i++)
fprintf(f, "%d %d %lu\n", i, Debug[i], MemCount[i]);
fclose(f);
}
else if (ch=='A') {
double sum = 0.0;
for (i=1; i<BufPtr; i++)
sum += MemCount[i];
printf("\nAverage MemCount = %lf.\n", sum/(BufPtr-1));
}
else if (ch=='C') {
printf("\nCurrent clip value %ld. Enter new value: ", clip);
scanf("%ld", &clip);
}
#ifdef GFX
else if (ch=='V') {
int gd=VGA, gm=VGAHI;
initgraph(&gd, &gm, "\\ borlandc\\ bgi");
base = 1;
while (base<BufPtr) {
for (i=0; i<640; i++) {
if (i+base>=BufPtr)
break;
putpixel(i, 479-(int)((double)479*MemCount[i+base]/clip), WHITE);
}
i = getch();
if (i==27) break;
base += 640;
cleardevice();
}
closegraph();
}
#endif
else if (ch=='T') {
clrscr();
base = 1;
while (base<BufPtr) {
for (i=0; i<640; i++) {
if (i+base>=BufPtr)
break;
if (MemCount[i+base] < clip) {
gotoxy(1+(i/8), 25-(int)((double)25*MemCount[i+base]/clip));
putch('X');
}
}
i = getch();
if (i==27) break;
base += 640;
clrscr();
}
}
}
while (ch != 'Q');
}
void interrupt far watch_port()
{
unsigned long c=0L;
int i;
if (BufPtr < BUFLEN) {
((unsigned char *)(&c))[0] = inportb(MC_READ0);
((unsigned char *)(&c))[1] = inportb(MC_READ1);
((unsigned char *)(&c))[2] = inportb(MC_READ2);
for (i=0; i<MAXTRIES; i++) {
outportb(MC_CLEAR, 0); /* clear counters */
if (inportb(MC_READ1)==0) { /* verify clear */
Debug[BufPtr] = i+1;
break;
}
}
MemCount[BufPtr++] = c;
}
_chain_intr(old_timertick);
}