/*
* "showmem.c" A C Norman, 1996-2007
*
* This program processes a "memory.use" log file created by CSL
* in a variant compiled with MEMORY_TRACE defined. It displays the
* memory use map and allows the user to zoom in using I and out using
* O, move left, right, up or down. V redraws viewing just the box.
* A "." input resets the image. The numbers displayed at the top left
* are as for use with "-m" in a CSL command line to provoke an exception
* when a memory reference in the box is first seen.
*
* This code uses the Watcom graphics library, so is DOS specific. Furthermore
* it is coded assuming you have a monitor suitable for 1024*768 in
* 256 colours.
*/
/*
* This code may be used and modified, and redistributed in binary
* or source form, subject to the "CCL Public License", which should
* accompany it. This license is a variant on the BSD license, and thus
* permits use of code derived from this in either open and commercial
* projects: but it does require that updates to this code be made
* available back to the originators of the package.
* Before merging other code in with this or linking this code
* with other packages or libraries please check that the license terms
* of the other material are compatible with those of this.
*/
/* Signature: 7e3ca32b 18-Jan-2007 */
#include <conio.h>
#include <graph.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
int main()
{
FILE *f = fopen("memory.use", "rb");
int c, c1, c2, len, col, nrecords;
int x, y, done;
double x1, y1, x2, y2, w;
double ox1, oy1, ox2, oy2;
int sx, sy;
unsigned i;
int zeros = 0, ones=0, onebyte = 0, twobyte = 0, threebyte = 0;
char buffer[100];
double a00, a01, a02, a10, a11, a12;
long int filepos;
if (f == NULL) return 1;
nrecords = getc(f) & 0xff;
nrecords = nrecords + ((getc(f) & 0xff) << 8);
nrecords = nrecords + ((getc(f) & 0xff) << 16);
len = getc(f) & 0xff;
len = len + ((getc(f) & 0xff) << 8);
len = len + ((getc(f) & 0xff) << 16);
a00 = 1020.0/(double)nrecords; a01 = 0.0; a02 = 2.0;
a10 = 0.0; a11 = -760.0/(2.0*(double)len); a12 = 768.0-4.0;
x1 = 0.0; y1 = 0.0; x2 = (double)nrecords; y2 = 2.0*(double)len;
#define X(x,y) ((int)(a00*x+a01*y+a02))
#define Y(x,y) ((int)(a10*x+a11*y+a12))
filepos = ftell(f);
_setvideomode(_XRES256COLOR); /* 1024 * 768 */
repaint:
_clearscreen(_GCLEARSCREEN);
_setcolor(15);
_settextposition(2, 2);
sprintf(buffer, "%d:%d:%d ", 0x400*(int)x1, (int)y1, (int)y2);
_outtext(buffer);
_rectangle(_GBORDER, X(x1,y1), Y(x1,y1), X(x2,y2), Y(x2,y2));
fseek(f, filepos, SEEK_SET);
for (x=0; ; x++)
{ col = 0;
c = kbhit();
if (c != 0) break;
for (;;)
{ c = getc(f);
if (c == EOF) break;
if ((c & 0x80) == 0)
{ if (c == 0) zeros++;
else if (c == 1) ones++;
onebyte++;
col += c;
}
else if ((c & 0x40) == 0)
{ c1 = getc(f) & 0xff;
if (c1 == 0)
{ if (c == 0x80) break; /* end of line code */
col += 0x400000*(c & 0x3f);
continue;
}
col += (c & 0x3f) + (c1 << 6);
twobyte++;
}
else
{ c1 = getc(f) & 0xff;
c2 = getc(f) & 0xff;
c = (c & 0x3f) + (c1 << 6) + (c2 << 14);
if (c < 0x40)
{ if (c == 0) c = 30;
else if (c == 16) c = 31;
_setcolor(c);
continue;
}
col += c;
threebyte++;
}
sx = X(x, col);
if (sx >= 0 && sx < 1024)
{ sy = Y(x, col);
if (sy >= 0 && sy < 768) _setpixel(X(x,col), Y(x,col));
}
}
if (c == EOF) break;
}
done = 0;
while (!done)
{ ox1 = x1, oy1 = y1;
ox2 = x2, oy2 = y2;
switch (tolower(getch()))
{
case 'q':
done = 1;
continue;
case '.':
x1 = 0.0; y1 = 0.0; x2 = (double)nrecords; y2 = 2.0*(double)len;
if (a00 != 1020.0/(double)nrecords ||
a01 != 0.0 ||
a02 != 2.0 ||
a10 != 0.0 ||
a11 != -760.0/(2.0*(double)len) ||
a12 != 768.0-4.0)
{ a00 = 1020.0/(double)nrecords; a01 = 0.0; a02 = 2.0;
a10 = 0.0; a11 = -760.0/(2.0*(double)len); a12 = 768.0-4.0;
goto repaint;
}
break;
case 'u':
w = (y2 - y1)/2.0;
y1 += w;
y2 += w;
break;
case 'd':
w = (y2 - y1)/2.0;
y1 -= w;
y2 -= w;
break;
case 'l':
w = (x2 - x1)/2.0;
x1 -= w;
x2 -= w;
break;
case 'r':
w = (x2 - x1)/2.0;
x1 += w;
x2 += w;
break;
case 'i':
w = (y2 - y1)/10.0;
y1 += w;
y2 -= w;
w = (x2 - x1)/10.0;
x1 += w;
x2 -= w;
break;
case 'o':
w = (y2 - y1)/10.0;
y1 -= w;
y2 += w;
w = (x2 - x1)/10.0;
x1 -= w;
x2 += w;
break;
case 'n':
w = (x2 - x1)/10.0;
x1 += w;
x2 -= w;
break;
case 'w':
w = (x2 - x1)/10.0;
x1 -= w;
x2 += w;
break;
case 'v':
a00 = -1018.0/(x1-x2);
a10 = 0.0;
a02 = 2.0*(510.0*x1 - x2)/(x1-x2);
a10 = 0.0;
a11 = 760.0/(y1-y2);
a12 = 4.0*(y1 - 191.0*y2)/(y1-y2);
goto repaint;
}
_setplotaction(_GXOR);
_setcolor(15);
_rectangle(_GBORDER, X(ox1,oy1), Y(ox1,oy1), X(ox2,oy2), Y(ox2,oy2));
_settextposition(2, 2);
sprintf(buffer, "%d:%d:%d ", 0x400*(int)x1, (int)y1, (int)y2);
_outtext(buffer);
_rectangle(_GBORDER, X(x1,y1), Y(x1,y1), X(x2,y2), Y(x2,y2));
_setplotaction(_GPSET);
}
_setvideomode(_DEFAULTMODE);
printf("len = %d bits, Max x was %d, nrecords = %d = %x\n",
2*len, x, nrecords, nrecords);
printf("zeros=%d ones=%d onebyte=%d twobyte=%d threebyte=%d\n",
zeros, ones, onebyte, twobyte, threebyte);
return 0;
}
/* end of showmem.c */