home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Monster Media 1994 #1
/
monster.zip
/
monster
/
MATH
/
C25SIM.ZIP
/
sample.c
< prev
next >
Wrap
Text File
|
1994-01-02
|
8KB
|
278 lines
/* ======================================================================= */
/* */
/* SAMPLE.C */
/* */
/* ======================================================================= */
#include "stdio.h"
#include "stdlib.h"
#include "conio.h"
#include "string.h"
#include "c25lib.h"
#define next_link(p) ((char *) *((int *)(p)))
#define set_next_link(p,n) *((char **) (p)) = n
#define string_part(p) (((char *) (p)) + sizeof(char *))
char toprint[100], *first_symbol, name[40], fline[80], dummy2[40];
/* ======================================================================= */
/* Wait States */
/* ======================================================================= */
void __write(char *s)
{
printf("%s", s);
}
#define ui(x) ((unsigned int) (x))
#define range(x,lo,hi) ((ui(x) >= ui(lo)) && (ui(x) <= ui(hi)))
int program_wait_states(unsigned int addr)
{
/* narrow range of very slow memory */
if (range(addr, 0x98, 0xA0)) return 10;
/* everything else is zero-wait-state */
return 0;
}
/* ======================================================================= */
/* Symbol Table */
/* ======================================================================= */
char *add_line(char **head, char *line)
{
char *p, *q;
q = (char *) malloc(sizeof(char *) + strlen(line) + 1);
if (q == NULL) return q;
strcpy(string_part(q), line);
set_next_link(q, NULL);
if (*head == NULL)
{
*head = q;
return q;
}
for (p = *head; next_link(p) != NULL; p = next_link(p));
set_next_link(p, q);
return q;
}
void load_map_file(char *word)
{
int i, addr, dummy1;
FILE *f;
for (i = 0; i < (int) strlen(word); i++) word[i] = toupper(word[i]);
if (strchr(word, '.') == NULL) sprintf(name, "%s.map", word);
else strcpy(name, word);
f = fopen(name, "r");
if (f == NULL)
{
printf("No map file available\n");
return;
}
while (1)
{
fgets(fline, 80, f);
if (strcmp(fline, "GLOBAL SYMBOLS\n") == 0) break;
if (feof(f)) { fclose(f); return; }
}
fgets(fline, 80, f);
fgets(fline, 80, f);
fgets(fline, 80, f);
first_symbol = NULL;
while (1)
{
fgets(fline, 80, f);
if (sscanf(fline, "%x %s %x %s", &addr, name, &dummy1, dummy2) < 4)
goto fini;
sprintf(fline, "%s %04X", name, addr);
if (add_line(&first_symbol, fline) == NULL)
{
__write("Out of room for labels and global variables!\n");
goto fini;
}
}
fini:
fclose(f);
return;
}
int lookup_symbol(char *name)
{
int n;
char *p, q[40];
for (p = first_symbol; p != NULL; p = next_link(p))
{
sscanf(string_part(p), "%s %x", q, &n);
if (strcmpi(q, name) == 0)
return n;
}
printf("Couldn't find symbol \"%s\"\n", name);
return 0;
}
int print_matching_symbols(int a)
{
char *p, q[40];
int x, n = 0;
for (p = first_symbol; p != NULL; p = next_link(p))
{
sscanf(string_part(p), "%s %x", q, &x);
if (x == a)
{
printf("%s\n", q);
n++;
}
}
return n;
}
int print_all_symbols(void)
{
char *p;
int n = 0;
for (p = first_symbol; p != NULL; p = next_link(p))
{
printf("%s\n", string_part(p));
n++;
}
return n;
}
/* ======================================================================= */
/* Main */
/* ======================================================================= */
int cp, rstring;
void note_change(int *current, int *previous, char *name)
{
if (*previous != *current)
{
/* print the new values */
printf("%ld cycles %s=%04X\n", cycles, name, *current);
/* and update the previous value */
*previous = *current;
}
}
char str[] = "Supercalifragilistic";
int strptr = 0;
void getch2(void)
{
switch (toupper(getch()))
{
case 0: getch(); break;
case 'Q': exit(0); break;
default: break;
}
}
void main(void)
{
int i, c, mode = 0,
*k, *L, id, i1, i2, ri_counter,
k_previous, L_previous, ar4_previous, ar5_previous;
unsigned long int next_rint;
/* First set up the simulator and load some files. */
initialize_simulator();
load_hex_files("foo"); /* C25 executable */
load_map_file("foo"); /* symbol table */
k = data_memory_address(lookup_symbol("_k"));
L = data_memory_address(lookup_symbol("_L"));
id = lookup_symbol("_idle_here");
i1 = lookup_symbol("tint");
i2 = lookup_symbol("rint");
cp = lookup_symbol("cptr");
rstring = lookup_symbol("rstring");
/* Set up wait states for slow program memory */
pwaitf = program_wait_states;
next_rint = 600;
while (1)
{
/* Execute one instruction */
advance();
/* Report only when something changes */
if (mode)
{
note_change(&ar[4], &ar4_previous, "ar4");
note_change(&ar[5], &ar5_previous, "ar5");
note_change(k, &k_previous, "k");
note_change(L, &L_previous, "L");
}
/* Footnote interrupts */
if (pc == i1)
printf("TINT Interrupt at cycle # %ld\n", cycles);
if (pc == i2)
printf("RINT Interrupt at cycle # %ld\n", cycles);
if (pc == id)
printf("Idle at cycle # %ld\n", cycles);
if (cycles >= next_rint)
{
drr = (int) str[strptr];
strptr = (strptr + 1) % (strlen(str) + 1);
c25_interrupt(RINT);
next_rint += 1200;
}
if (kbhit())
switch (toupper(getch()))
{
/* Pressing Q will quit the program */
case 'Q':
return;
/* Pressing R will get a long report */
case 'R':
long_report();
break;
/* Pressing M will toggles k,L report mode */
case 'M':
mode = !mode;
break;
/* Pressing S will print the received string */
case 'S':
i = rstring;
while ((c = read_data_memory(i++)) != 0)
printf("%c", (char) c);
printf("\n");
getch2();
break;
/* Pressing any other key will get a short report */
default:
short_report();
getch2();
break;
}
}
}