885 lines
31 KiB
C
885 lines
31 KiB
C
/* =====> SDUMP.C */
|
||
/* TIPC Scheme '84 - Diagnostic Dump Routines
|
||
(C) Copyright 1984,1985,1987 by Texas Instruments Incorporated.
|
||
All rights reserved.
|
||
|
||
Author: John Jensen
|
||
Installation: Texas Instruments Incorporated, Dallas, Texas
|
||
Division: Central Research Laboratories
|
||
Cost Center: Computer Science Laboratory
|
||
Project: Computer Architecture Branch
|
||
Date Written: 11 April 1984
|
||
Modification History:
|
||
?? 10/10/85 - ??
|
||
rb 9/21/87 - lists, strings/symbols, and array-like data structures
|
||
print only within user-specified bounds;
|
||
also, hitting any key exits the printing
|
||
*/
|
||
#include "scheme.h"
|
||
#include "ctype.h"
|
||
#include "schars.h"
|
||
#include "slist.h"
|
||
|
||
#define INTR_OUTPUT if (char_rdy()) {(void) getch(); goto bye;}
|
||
|
||
static char *page_type[NUMTYPES] = {"LIST","FIX" ,"FLO" , "BIG","SYM" ,
|
||
"STR" ,"ARY" ,"CONT","CLOS","FREE",
|
||
"CODE","REF" ,"PORT","CHAR","ENV"};
|
||
/* character strings for getmem/rlsmem error message text */
|
||
static char *mem_fmt = "%s: %smem error\n";
|
||
static char *getmem_error = "get";
|
||
|
||
char *getmem();
|
||
char char_rdy();
|
||
|
||
/**********************************************************************/
|
||
/* Format a dump of the Page Table */
|
||
/**********************************************************************/
|
||
dump_page_table()
|
||
{
|
||
int i; /* the usual index variable */
|
||
int start, end; /* starting and ending limits of FREE pages */
|
||
int space[NUMPAGES]; /* amount of free space in each page */
|
||
ENTER(dump_page_table);
|
||
|
||
/* determine the amount of free space in each page */
|
||
sum_space(space);
|
||
|
||
/* Print Page Table Dump Headings */
|
||
printf("\nDump of Scheme Memory Management Page Tables\n\n%s\n%s\n%s\n",
|
||
"Page Page Base Next Link Free",
|
||
" No Type Para Avail Page Size Bytes Attributes",
|
||
"---- ---- ---- ----- ---- ---- ----- ----------");
|
||
start = end = -1;
|
||
for (i = 0; i < nextpage; i++)
|
||
{
|
||
INTR_OUTPUT;
|
||
if (ptype[i] == FREETYPE*2) {
|
||
if (start < 0) start = i;
|
||
end = i;
|
||
}
|
||
else {
|
||
prt_free(&start, &end);
|
||
printf("%4x %5s %04x %4x %4x%c %4x %4x ", i,
|
||
page_type[ptype[i]>>1], getbase(i*2), nextcell[i],
|
||
pagelink[i], (i == pagelist[CORRPAGE(ptype[i])] ? '<' : ' '),
|
||
psize[i], space[i]);
|
||
/* print attributes for page */
|
||
prt_atr(i);
|
||
|
||
/* Flush line to output device */
|
||
printf("\n");
|
||
} /* end: else */
|
||
} /* end: for (i = 0; i < nextpage; i++) */
|
||
prt_free(&start, &end);
|
||
|
||
/* Print summary of pages which are not allocated */
|
||
if (nextpage < NUMPAGES) {
|
||
if (nextpage == NUMPAGES-1)
|
||
printf("Page %x is not allocated\n", nextpage);
|
||
else
|
||
printf("Pages %x-%x are not allocated\n", nextpage, NUMPAGES-1);
|
||
}
|
||
bye:
|
||
} /* end of function: dump_page_table() */
|
||
|
||
/**********************************************************************/
|
||
/* Print Page Attributes */
|
||
/* */
|
||
/* Purpose: This routine prints the attributes of a page on the */
|
||
/* current print line. Attributes are separated by commas. */
|
||
/**********************************************************************/
|
||
prt_atr(page)
|
||
int page;
|
||
{
|
||
unsigned bits;
|
||
static char *things[16] = {"atom","list","fixnum","flonum","bignum",
|
||
"symbol","string","array","no memory","read only",
|
||
"continuation","closure","ref","port","code block",
|
||
"char"};
|
||
char *comma_needed = "";
|
||
int i = 0;
|
||
ENTER(prt_atr);
|
||
|
||
bits = w_attrib[page];
|
||
while (bits)
|
||
{
|
||
if (bits & 0x8000)
|
||
{
|
||
printf("%s%s", comma_needed, things[i]);
|
||
comma_needed = ",";
|
||
}
|
||
i++;
|
||
bits = (bits << 1);
|
||
} /* end: while (bits) */
|
||
}
|
||
|
||
/**********************************************************************/
|
||
/* Print Free (unused) Pages of Memory */
|
||
/* */
|
||
/* Purpose: Given a range of unused pages of memory, this routine */
|
||
/* formats a message to indicate the presence of said pages.*/
|
||
/**********************************************************************/
|
||
prt_free(start, end)
|
||
int *start, *end;
|
||
{
|
||
int i;
|
||
ENTER(prt_free);
|
||
if ((i = *start) >= 0)
|
||
{
|
||
if (i == *end)
|
||
printf("%4x %4s %04x %4x %4x %4x %4x (unused)\n", i,
|
||
page_type[ptype[i]>>1], getbase(i*2), nextcell[i],
|
||
pagelink[i], psize[i], psize[i]);
|
||
else
|
||
printf("Pages %x-%x are allocated, but unused\n",
|
||
i, *end);
|
||
*start = *end = -1;
|
||
}
|
||
}
|
||
|
||
/**********************************************************************/
|
||
/* Produce a Formatted Dump of an Area of Scheme's Address Space */
|
||
/**********************************************************************/
|
||
dump_memory(page, disp, length)
|
||
int page; /* number of page to dump */
|
||
unsigned disp; /* starting displacement */
|
||
unsigned length; /* number of bytes to dump */
|
||
{
|
||
int page_type;
|
||
static char *description[NUMTYPES] = {"List Cells","Fixnums","Flonums",
|
||
"Bignums","Symbols","Strings",
|
||
"Arrays","Continuation Cells",
|
||
"Closures","Nothing (unused)",
|
||
"Code","Ref Cells","Ports",
|
||
"Characters", "Environments"};
|
||
ENTER(dump_memory);
|
||
page_type = ptype[page]>>1;
|
||
if (page_type >= 0 && page_type < NUMTYPES && page_type != FREETYPE)
|
||
{
|
||
printf("Page %x (hex) contains %s\nPage attributes: ",
|
||
page, description[page_type]);
|
||
prt_atr(page);
|
||
printf("\n");
|
||
switch (page_type)
|
||
{
|
||
case LISTTYPE:
|
||
dump_list(page, disp, length);
|
||
break;
|
||
/*** Note: Fixnums and Characters currently handled as immediates
|
||
case CHARTYPE:
|
||
case FIXTYPE:
|
||
dump_fix(page, disp, length);
|
||
break;
|
||
***/
|
||
case SYMTYPE:
|
||
case STRTYPE:
|
||
dump_str(page, disp, length);
|
||
break;
|
||
|
||
case CODETYPE:
|
||
dump_code(page, disp, length);
|
||
break;
|
||
|
||
case ARYTYPE:
|
||
case CLOSTYPE:
|
||
case CONTTYPE:
|
||
case ENVTYPE:
|
||
dump_ary(page, disp, length);
|
||
break;
|
||
|
||
case FLOTYPE:
|
||
/*** dump_flo(page, disp, length);
|
||
break; ***/
|
||
|
||
case PORTTYPE:
|
||
/*** dump_port(page,disp,length);
|
||
break; ***/
|
||
|
||
case BIGTYPE:
|
||
dump_hex(page, disp, length);
|
||
break;
|
||
|
||
case REFTYPE:
|
||
default: printf("***Invalid page type: %d***\n", page_type);
|
||
} /* end: switch (page_type) */
|
||
} /* end: if (then clause) */
|
||
else
|
||
printf("***Invalid page type: %d***\n", page_type);
|
||
} /* end of function: dump_memory(page, disp, length) */
|
||
|
||
|
||
/**********************************************************************/
|
||
/* Produce a Hex Dump of a Page of Scheme's Memory */
|
||
/**********************************************************************/
|
||
dump_hex(page, disp, length)
|
||
int page, disp, length;
|
||
{
|
||
int start, end; /* delimiters for dump area */
|
||
ENTER(dump_hex);
|
||
|
||
start = disp & 0xFFF0;
|
||
end = ((disp + length + 15) & 0xFFF0) - 1;
|
||
|
||
while (start <= end) {
|
||
INTR_OUTPUT;
|
||
if ((start & 0x000F) == 0) { /* start of new line */
|
||
printf("\n%2x:%04x ", page, start);
|
||
}
|
||
printf("%02x ", get_byte(page, start));
|
||
start++;
|
||
}
|
||
/* flush line to output device */
|
||
bye: printf("\n");
|
||
}
|
||
|
||
|
||
/**********************************************************************/
|
||
/* Produce Formatted Dump of a Page Containing List Cells */
|
||
/* */
|
||
/* Note: the "disp" and "length" parameters currently are not used. */
|
||
/* (they are now -- rb 9/21/87) */
|
||
/**********************************************************************/
|
||
dump_list(page, disp, length)
|
||
int page;
|
||
int disp;
|
||
int length;
|
||
{
|
||
int end_disp = disp + length;
|
||
int count = 0;
|
||
int i,j; /* the usual index variables */
|
||
int next;
|
||
int number_of_cells; /* the number of list cells in current page */
|
||
int page_length; /* length of current page in bytes */
|
||
int start = -1;
|
||
int end = -1;
|
||
char *unused_cells;
|
||
ENTER(dump_list);
|
||
|
||
/* if page zero, print nil */
|
||
if (page == 0)
|
||
{
|
||
printf("000:0000 00 0000 00 0000 nil\n");
|
||
} /* end: if (page == 0) then ... */
|
||
else /* page != 0 */
|
||
{
|
||
number_of_cells = (page_length = psize[page])/LISTSIZE;
|
||
if (!(unused_cells = getmem(number_of_cells)))
|
||
{
|
||
printf(mem_fmt, rtn_name, getmem_error); goto end_routine;
|
||
}
|
||
/* count up available cells */
|
||
for (i=0; i < number_of_cells; i++) unused_cells[i] = '\0';
|
||
next = nextcell[page];
|
||
while (next != END_LIST) {
|
||
j = next/LISTSIZE;
|
||
ASSERT(j >= 0 && j < number_of_cells /* subchk? */ );
|
||
unused_cells[j] = 'x';
|
||
next = get_word(page, next+1);
|
||
count++;
|
||
ASSERT(count <= number_of_cells /* infinite loop? */);
|
||
} /* end while */
|
||
printf("%d (decimal) List Cells Unused\n", count);
|
||
|
||
/* print active List Cells */
|
||
for (next = 0; next <= page_length - LISTSIZE; next += LISTSIZE) {
|
||
INTR_OUTPUT;
|
||
if (unused_cells[next/LISTSIZE]) { /* unused cell-- make a notation */
|
||
if (start < 0) start = next;
|
||
end = next;
|
||
}
|
||
else {
|
||
if (end >= disp && start <= end_disp)
|
||
prt_unused(&start, &end);
|
||
if (next+LISTSIZE >= disp && next < end_disp)
|
||
printf("%3x:%04x %02x %04x %02x %04x\n", page, next,
|
||
CORRPAGE(get_byte(page, next)), get_word(page, next+1),
|
||
CORRPAGE(get_byte(page, next+3)), get_word(page, next+4));
|
||
}
|
||
} /* end for (next=0; ... */
|
||
if (end >= disp && start <= end_disp)
|
||
prt_unused(&start, &end);
|
||
|
||
/* release memory for unused cell list */
|
||
bye:
|
||
if (rlsmem(unused_cells, number_of_cells))
|
||
rlsmem_error(rtn_name);
|
||
} /* end: else /* page != 0 */ */
|
||
end_routine:
|
||
} /* end of function: dump_list(page) */
|
||
|
||
|
||
/***** Code for dump_ref turned off 6 July 1985 by John Jensen *****
|
||
/**********************************************************************/
|
||
/* Produce Formatted Dump of a Page Containing Reference Cells */
|
||
/* */
|
||
/* Note: the "disp" and "length" parameters currently are not used. */
|
||
/**********************************************************************/
|
||
dump_ref(page, disp, length)
|
||
int page;
|
||
int disp;
|
||
int length;
|
||
{
|
||
int count = 0;
|
||
int end = -1;
|
||
int i,j; /* the usual index variables */
|
||
int next;
|
||
int number_of_cells; /* the number of cells in current page */
|
||
int page_length; /* size of the current page in bytes */
|
||
int start = -1;
|
||
char *unused_cells;
|
||
ENTER(dump_ref);
|
||
|
||
number_of_cells = (page_length = psize[page])/PTRSIZE;
|
||
if (!(unused_cells = getmem(number_of_cells)))
|
||
{
|
||
printf(mem_fmt, rtn_name, getmem_error); goto end_routine;
|
||
}
|
||
/* count up available cells */
|
||
for (i=0; i < number_of_cells; i++) unused_cells[i] = '\0';
|
||
next = nextcell[page];
|
||
while (next != END_LIST)
|
||
{
|
||
j = next/PTRSIZE;
|
||
ASSERT(j >= 0 && j < number_of_cells /* subchk? */);
|
||
unused_cells[j] = 'x';
|
||
next = get_word(page, next+1);
|
||
count++;
|
||
ASSERT(count <= number_of_cells /* infinite loop? */);
|
||
}
|
||
printf("%d (decimal) Reference Cells Unused\n", count);
|
||
|
||
/* print active Ref Cells */
|
||
for (next = 0; next <= page_length - PTRSIZE; next += PTRSIZE)
|
||
{
|
||
if (unused_cells[next/PTRSIZE])
|
||
{ /* unused cell-- make a notation */
|
||
if (start < 0) start = next;
|
||
end = next;
|
||
}
|
||
else
|
||
{
|
||
prt_unused(&start, &end);
|
||
printf("%3x:%04x %02x %04x\n", page, next,
|
||
CORRPAGE(get_byte(page, next)), get_word(page, next+1));
|
||
}
|
||
} /* end: for next=0; next<=page_length-PTRSIZE; next+=PTRSIZE) */
|
||
prt_unused(&start, &end);
|
||
if (rlsmem (unused_cells, number_of_cells))
|
||
{
|
||
rlsmem_error(rtn_name);
|
||
}
|
||
end_routine:
|
||
} /* end of function: dump_ref(page) */
|
||
***** Code for dump_ref turned off 6 July 1985 by John Jensen *****/
|
||
|
||
/**********************************************************************/
|
||
/* Produce a Formatted Dump of a String/Symbol Page */
|
||
/**********************************************************************/
|
||
dump_str(page, disp, length)
|
||
int page, disp, length;
|
||
{
|
||
int end_disp = disp + length; /* display only between disp and end_disp */
|
||
char buffer[70]; /* print line buffer */
|
||
int ch; /* character (byte) begin formatted */
|
||
int char_ptr; /* pointer into print line buffer */
|
||
int count; /* count of bytes in print line buffer */
|
||
int first_time; /* flag indicating first time through loop */
|
||
int hex_ptr; /* pointer into print line buffer */
|
||
int hold_addr; /* address value to print */
|
||
int i,j; /* index variables */
|
||
int incr; /* adjustment for header overhead */
|
||
int next = 0; /* pointer to next block of memory in page */
|
||
int page_length; /* length in bytes of the page we're dumping */
|
||
int size; /* size of string/symbol in bytes */
|
||
int type; /* type code block of memory */
|
||
static char hex_digit[16] = {'0','1','2','3','4','5','6','7','8','9',
|
||
'A','B','C','D','E','F'};
|
||
ENTER(dump_str);
|
||
|
||
page_length = psize[page];
|
||
while (next <= page_length - BLK_OVHD) {
|
||
type = (i = get_byte(page, next)) & 0x003F;
|
||
size = get_word(page, next+1);
|
||
if (size < 0) size = BLK_OVHD + PTRSIZE; /* check for small string */
|
||
ASSERT(size >= 3 && size <= page_length - next /* invalid size */);
|
||
if (next+size >= disp && next <= end_disp) {
|
||
if (type == FREETYPE) {
|
||
printf("%3x:%04x unused block of %x (hex) bytes\n",
|
||
page, next, size);
|
||
}
|
||
else /* type != FREETYPE */ {
|
||
printf("%3x:%04x %02x %04x block type = %d size = %d (decimal) bytes\n",
|
||
page, next, i, size, type, size);
|
||
if (type == SYMTYPE) {
|
||
printf(" Link: %02x %04x Hash Key: %02x\n",
|
||
get_byte(page,next+3), get_word(page,next+4),
|
||
get_byte(page,next+6));
|
||
incr = 7;
|
||
}
|
||
else incr = 3;
|
||
for (first_time = 1, count = 16, i = next+incr; i < next+size; i++) {
|
||
INTR_OUTPUT;
|
||
if (count >= 16) {
|
||
if (!first_time) printf("%3x:%04x %s\n", page, hold_addr, buffer);
|
||
hold_addr = i;
|
||
for (j = 0; j < sizeof(buffer); j++) buffer[j] = ' ';
|
||
buffer[49] = buffer[66] = '|';
|
||
buffer[sizeof(buffer)-1] = '\0';
|
||
hex_ptr = count = first_time = 0;
|
||
char_ptr = 50;
|
||
} /* end: if (then clause) */
|
||
if ((ch = get_byte(page, i)) != '\0') buffer[char_ptr] = ch;
|
||
buffer[hex_ptr] = hex_digit[ch >> 4];
|
||
buffer[hex_ptr+1] = hex_digit[ch & 0x000F];
|
||
count++;
|
||
char_ptr++;
|
||
hex_ptr += 3;
|
||
} /* end for ... */
|
||
printf("%3x:%04x %s\n", page, hold_addr, buffer);
|
||
} /* end else */
|
||
} /* end if */
|
||
next += size;
|
||
} /* end: while (next < page_length) */
|
||
bye:
|
||
} /* end of function: dump_str(page, disp, length) */
|
||
|
||
|
||
/**********************************************************************/
|
||
/* Format a Page Containing Code Blocks */
|
||
/**********************************************************************/
|
||
dump_code(page, start, length)
|
||
int page, start, length;
|
||
{
|
||
/*%%int ch; /* character (byte) begin formatted */*/
|
||
/*%%int char_ptr; /* pointer into print line buffer */*/
|
||
/*%%int count; /* count of bytes in print line buffer */*/
|
||
int disp;
|
||
int end; /* end of print range */
|
||
int ent; /* entry offset of code */
|
||
/*%%int first_time; /* flag indicating first time through loop */*/
|
||
/*%%int hex_ptr; /* pointer into print line buffer */*/
|
||
/*%%int hold_addr; /* address value to print */*/
|
||
/*%%int i,j; /* index variables */*/
|
||
int next = 0; /* pointer to next block of memory in page */
|
||
int page_length; /* length in bytes of the page we're dumping */
|
||
int pc;
|
||
int size; /* size of string/symbol in bytes */
|
||
int tag; /* page number field of a constant ptr */
|
||
char *title; /* pointer to "constants" title */
|
||
int type; /* type code block of memory */
|
||
/*%%static char hex_digit[16] = {'0','1','2','3','4','5','6','7','8','9',*/
|
||
/*%% 'A','B','C','D','E','F'};*/
|
||
ENTER(dump_code);
|
||
|
||
end = start + length;
|
||
page_length = psize[page];
|
||
while (next <= page_length - BLK_OVHD) {
|
||
type = get_byte(page, next) & 0x003F;
|
||
size = get_word(page, next+1);
|
||
ASSERT(size >= 3 && size <= page_length - next /* invalid size */);
|
||
if (type == FREETYPE) {
|
||
if ((next >= start && next <= end) ||
|
||
(next+size > start && next+size <= end) ||
|
||
(next <= start && next+size-1 >= end)) {
|
||
printf("%3x:%04x unused block of %d (decimal) bytes\n",
|
||
page, next, size);
|
||
}
|
||
}
|
||
else /* type != FREETYPE */ {
|
||
ent = get_word(page, next+4);
|
||
if (next >= start && next <= end) {
|
||
printf(
|
||
"%3x:%04x %02x %04x block type = %d size = %d (decimal) bytes\n",
|
||
page, next, type, size, type, size);
|
||
printf("Code begins at %d (decimal)\n", ent);
|
||
}
|
||
pc = next + PTRSIZE*2;
|
||
title = "Constants:\n";
|
||
while (pc < next + ent) {
|
||
INTR_OUTPUT;
|
||
if (pc >= start && pc <= end) {
|
||
tag = CORRPAGE(get_byte(page, pc));
|
||
disp = get_word(page, pc+1);
|
||
printf("%s%3x:%04x ", title, page, pc);
|
||
annotate(tag, disp); /* describe what's being pointed at */
|
||
title = ""; /* print heading only once */
|
||
}
|
||
pc += PTRSIZE;
|
||
} /* end: while (pc < next + entry) */
|
||
|
||
/* format the instructions in the block */
|
||
while (pc < next + size) {
|
||
INTR_OUTPUT;
|
||
t_inst(page, &pc, 0, (pc >= start && pc <= end));
|
||
} /* end: while (pc < next + size) */
|
||
} /* end: else */
|
||
next += size;
|
||
} /* end: while (next < page_length) */
|
||
bye:
|
||
} /* end of function: dump_code(page, start, length) */
|
||
|
||
|
||
/**********************************************************************/
|
||
/* Dump the port page */
|
||
/* */
|
||
/* Note: DISP and LENGTH arguments are not used here. */
|
||
/**********************************************************************/
|
||
/*****
|
||
dump_port(page,disp,length)
|
||
int page,disp,length;
|
||
{
|
||
int c; /* Next input character */
|
||
int csrcol; /* Port cursor column */
|
||
int i; /* Index variable */
|
||
int lnlen; /* Port line length */
|
||
int next = 0; /* Pointer to next block in page */
|
||
int page_length; /* Length in bytes of page */
|
||
int ptype; /* Type of port */
|
||
int size; /* Size of port in bytes */
|
||
int type; /* Type code block of memory */
|
||
|
||
ENTER(dump_port);
|
||
|
||
page_length = psize[page];
|
||
while (next < page_length)
|
||
{
|
||
type = get_byte(page,next) & 0x003F;
|
||
size = get_word(page,next+1);
|
||
ASSERT(size >= 46 && size <= page_length - next /* invalid size */);
|
||
if (type == FREETYPE)
|
||
{
|
||
printf("%3x:%04x unused block of %d (decimal) bytes\n",
|
||
page,next,size);
|
||
}
|
||
else /* type != FREETYPE */
|
||
{
|
||
printf(
|
||
"%3x:%04x %02x %04x block type = %d size = %d (decimal) bytes \n",
|
||
page, next, type, size, type, size);
|
||
ptype = get_byte(page,next+3);
|
||
switch (ptype)
|
||
{
|
||
case 0:
|
||
printf(" Output port writing to ");
|
||
break;
|
||
case 1:
|
||
printf(" Input port receiving from ");
|
||
break;
|
||
}
|
||
/* Now print file name */
|
||
i = 10;
|
||
while ((i < 18) && ((c = get_byte(page,next+i)) != ' '))
|
||
{
|
||
printf("%c",toupper(c));
|
||
i++;
|
||
}
|
||
i = 18;
|
||
printf(".");
|
||
while ((i < 21) && ((c = get_byte(page,next+i)) != ' '))
|
||
{
|
||
printf("%c", toupper(c));
|
||
i++;
|
||
}
|
||
printf("\n");
|
||
lnlen = get_word(page,next+4);
|
||
csrcol = get_word(page,next+6);
|
||
switch (ptype)
|
||
{
|
||
case 0:
|
||
printf(" Line length: %d Print column: %d\n",
|
||
lnlen, csrcol);
|
||
break;
|
||
case 1:
|
||
c = get_byte(page, next+8);
|
||
printf(" Most recent character: %02x\n",c);
|
||
break;
|
||
}
|
||
} /* End of ELSE */
|
||
next += size;
|
||
} /* End of WHILE */
|
||
} /* End of function: dump_port(page,disp,length) */
|
||
*****/
|
||
|
||
/**********************************************************************/
|
||
/* Format a Page Containing Arrays or Continuations */
|
||
/**********************************************************************/
|
||
dump_ary(page, disp, length)
|
||
int page, disp, length;
|
||
{
|
||
/*%%int ent; /* entry offset of code */*/
|
||
int start_disp = disp; /* only values in range start_disp..end_disp
|
||
are displayed */
|
||
int end_disp = disp + length;
|
||
int i;
|
||
unsigned next = 0; /* pointer to next block of memory in page */
|
||
unsigned page_length; /* length of the current page in bytes */
|
||
int pc;
|
||
unsigned size; /* size of string/symbol in bytes */
|
||
int tag; /* page number field of a constant ptr */
|
||
int type; /* type code block of memory */
|
||
ENTER(dump_ary);
|
||
|
||
page_length = psize[page];
|
||
while (next <= page_length - BLK_OVHD) {
|
||
type = get_byte(page, next) & 0x003F;
|
||
size = get_word(page, next+1);
|
||
ASSERT(size >= 3 && size <= page_length - next /* invalid size */);
|
||
if (next+size >= start_disp && next <= end_disp) {
|
||
if (type == FREETYPE) {
|
||
printf("%3x:%04x unused block of %d (decimal) bytes\n",
|
||
page, next, size);
|
||
}
|
||
else /* type != FREETYPE */ {
|
||
printf(
|
||
"%3x:%04x %02x %04x tag = %d (%s) size = %d (decimal) bytes\n",
|
||
page, next, type, size, type, page_type[type], size);
|
||
pc = next + PTRSIZE;
|
||
while (pc < next + size) {
|
||
INTR_OUTPUT;
|
||
tag = CORRPAGE(get_byte(page, pc));
|
||
disp = get_word(page, pc+1);
|
||
/* see if following array entries are same as the current one */
|
||
for (i = pc + PTRSIZE; i < next + size; i += PTRSIZE) {
|
||
if (tag != CORRPAGE(get_byte(page, i)) ||
|
||
disp != get_word(page, i+1)) break;
|
||
} /* end for (i = pc + PTRSIZE; ... */
|
||
if (i >= start_disp && pc+PTRSIZE <= end_disp) {
|
||
if (i > pc + PTRSIZE) { /* consecutive entries with same value? */
|
||
/* if so, print address range */
|
||
printf("%3x:%04x-%2x:%04x ", page, pc, page, i-PTRSIZE);
|
||
}
|
||
else /* no consecutive entries with same value */ {
|
||
printf("%3x:%04x ", page, pc);
|
||
} /* end else */
|
||
annotate(tag, disp); /* describe what's being pointed at */
|
||
} /* end if (i >= disp ... */
|
||
pc = i;
|
||
} /* end while (pc < next + size) */
|
||
} /* end else */
|
||
} /* end if */
|
||
next += size;
|
||
} /* end: while (next < page_length) */
|
||
bye:
|
||
} /* end of function: dump_ary(page, disp, length) */
|
||
|
||
|
||
/**********************************************************************/
|
||
/* Dump the runtime stack */
|
||
/**********************************************************************/
|
||
dump_stk()
|
||
{
|
||
int next;
|
||
int ptr_disp, ptr_page;
|
||
ENTER(dump_stk);
|
||
|
||
/* print the value of PREV_reg and the stack base */
|
||
prt_reg(-4);
|
||
printf("BASE %04x (%u decimal)\n", BASE, BASE);
|
||
|
||
/* print active Stack Cells */
|
||
for (next = 0; next <= TOS; next += PTRSIZE) {
|
||
INTR_OUTPUT;
|
||
ptr_page = CORRPAGE(S_stack[next]);
|
||
ptr_disp = (S_stack[next+2]<<8) + S_stack[next+1];
|
||
printf("%s%04x ", (next==FP ? "FP->" : " "), next + BASE);
|
||
|
||
/* for values, show the value the stack entry points to */
|
||
annotate(ptr_page, ptr_disp);
|
||
|
||
} /* end: for (next = 0; next <= TOS; next += PTRSIZE) */
|
||
bye:
|
||
} /* end of function: dump_stk() */
|
||
|
||
|
||
prt_unused(start, end)
|
||
int *start, *end;
|
||
{
|
||
ENTER(prt_unused);
|
||
if (*start >= 0)
|
||
{
|
||
if (*start == *end)
|
||
printf("Location %04x unused\n", *start);
|
||
else
|
||
printf("Locations %04x-%04x unused\n", *start, *end);
|
||
*start = *end = -1;
|
||
}
|
||
} /* end of function: prt_unused(start, end) */
|
||
|
||
|
||
/**********************************************************************/
|
||
/* Dump the VM's Registers */
|
||
/**********************************************************************/
|
||
dump_regs()
|
||
{
|
||
int i; /* the usual index variable */
|
||
int *reg_page, *reg_disp;
|
||
int pc = S_pc;
|
||
long unbound; /* an "unbound" pointer */
|
||
|
||
long make_ptr();
|
||
|
||
unbound = make_ptr(UN_PAGE, UN_DISP);
|
||
|
||
/* Print the Contents of the general purpose registers */
|
||
reg_page = ®0_page;
|
||
reg_disp = ®0_disp;
|
||
for (i = 0; i < NUM_REGS; i++, reg_page+=2, reg_disp+=2)
|
||
if (regs[i] != unbound) prt_reg(i);
|
||
|
||
prt_reg(-1); /* print FNV */
|
||
prt_reg(-3); /* print GNV */
|
||
prt_reg(-2); /* print CB */
|
||
if(tmp_page & 1)printf("odd tmp_page\n");
|
||
printf("tmp_reg "); annotate(CORRPAGE(tmp_page), tmp_disp);
|
||
(void) t_inst(CORRPAGE(CB_pag), &pc,
|
||
/* run= */ FALSE, /* display= */ TRUE);
|
||
} /* end of function: dump_regs() */
|
||
|
||
prt_reg(reg)
|
||
int reg; /* register number to print (-2=CB, -1=FNV) */
|
||
{
|
||
int *disp;
|
||
int *page;
|
||
|
||
page = ®0_page + reg + reg;
|
||
disp = ®0_disp + reg + reg;
|
||
|
||
/* print the register name and contents */
|
||
switch (reg) {
|
||
case -1: printf("FNV ");
|
||
page = &FNV_pag;
|
||
disp = &FNV_dis;
|
||
break;
|
||
case -2: printf("CB ");
|
||
page = &CB_pag;
|
||
disp = &CB_dis;
|
||
break;
|
||
case -3: printf("GNV ");
|
||
page = &GNV_pag;
|
||
disp = &GNV_dis;
|
||
break;
|
||
case -4: printf("PREV ");
|
||
page = &PREV_pag;
|
||
disp = &PREV_dis;
|
||
break;
|
||
default: printf("R%d ", reg);
|
||
}
|
||
|
||
/* expound on what pointer is */
|
||
annotate(CORRPAGE(*page), *disp);
|
||
}
|
||
|
||
/* Print information about what a pointer points to */
|
||
annotate(page, disp)
|
||
int page, disp;
|
||
{
|
||
int ch;
|
||
int count;
|
||
char dlm = '\"'; /* string/symbol delimiter */
|
||
int i; /* index variable */
|
||
int incr = 3; /* adjustment for string/symbol header */
|
||
char *str; /* pointer to a character string */
|
||
int type; /* object type code */
|
||
double get_flo();
|
||
|
||
type = ptype[page]>>1;
|
||
|
||
printf("%2x:%04x %s", page, disp, page_type[type]);
|
||
|
||
/* for values, show the value the register points to */
|
||
switch (type)
|
||
{
|
||
case SYMTYPE: incr = 7; /* note: control falls through STRTYPE */
|
||
dlm = '|';
|
||
|
||
case STRTYPE: count = get_word(page, disp+1) - incr;
|
||
if (count > 40) count = 40;
|
||
disp += incr;
|
||
printf(" %c",dlm);
|
||
while (count > 0)
|
||
{
|
||
ch = get_byte(page, disp);
|
||
printf("%c", ch); disp++; count--;
|
||
}
|
||
printf("%c\n",dlm);
|
||
break;
|
||
|
||
case FIXTYPE: printf(" %d\n", get_fix(page, disp));
|
||
break;
|
||
|
||
case FLOTYPE: printf(" %g\n", get_flo(page,disp));
|
||
break;
|
||
|
||
case CHARTYPE: ch = get_char(page, disp);
|
||
str = " ";
|
||
*str = ch;
|
||
for (i = 0; i < test_num; i++)
|
||
{
|
||
if (ch == test_char[i])
|
||
{
|
||
str = test_string[i];
|
||
break;
|
||
}
|
||
}
|
||
printf(" #\\%s\n", str);
|
||
break;
|
||
|
||
case LISTTYPE: if (page == 0) printf(" nil");
|
||
default: printf("\n");
|
||
} /* end: switch (type) */
|
||
} /* end of function: annotate(page, disp) */
|
||
|
||
/************************************************************************/
|
||
/* Dump Environment */
|
||
/************************************************************************/
|
||
|
||
dump_environment(page, disp)
|
||
int page; /* page number of current environment entry */
|
||
int disp; /* displacement of current environment entry */
|
||
{
|
||
extern int display;
|
||
extern int show;
|
||
int search[2];
|
||
int pair[2];
|
||
int sym[2];
|
||
char *symbol; /* globally bound symbol (character representation) */
|
||
|
||
char *symbol_name(); /* retrieves a symbol's print name */
|
||
|
||
search[C_PAGE] = page;
|
||
search[C_DISP] = disp;
|
||
while (search[C_PAGE]) {
|
||
INTR_OUTPUT;
|
||
|
||
/* fetch pointer to symbol/value pair */
|
||
mov_reg(pair, search);
|
||
take_car(pair);
|
||
|
||
/* fetch pointer to symbol */
|
||
mov_reg(sym, pair);
|
||
take_car(sym);
|
||
|
||
/* retrieve symbol's print name and print said */
|
||
symbol = symbol_name(CORRPAGE(sym[C_PAGE]), sym[C_DISP]);
|
||
printf("%s\n", symbol);
|
||
rlsstr(symbol);
|
||
|
||
/* display the value currently bound to the symbol */
|
||
take_cdr(pair);
|
||
annotate(CORRPAGE(pair[C_PAGE]), pair[C_DISP]);
|
||
ssetadr(ADJPAGE(OUT_PAGE), OUT_DISP);
|
||
display = show = 1;
|
||
sprint(CORRPAGE(pair[C_PAGE]), pair[C_DISP], ADJPAGE(OUT_PAGE),
|
||
OUT_DISP);
|
||
|
||
outchar('\015');
|
||
outchar('\015');
|
||
|
||
/* follow linked list in cdr field */
|
||
take_cdr(search);
|
||
|
||
} /* end: while (search[C_PAGE]) */
|
||
bye:
|
||
} /* end of function: dump_environment() */
|
||
|