You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
471 lines
9.7 KiB
C
471 lines
9.7 KiB
C
#include <string.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
|
|
#include <SDL/SDL.h>
|
|
|
|
#include "video/gbuffer.h"
|
|
#include "cpu/65el02.h"
|
|
#include "memory/memory.h"
|
|
#include "debug.h"
|
|
#include "calc.h"
|
|
#include "monitor.h"
|
|
#include "screen.h"
|
|
#include "display/display.h"
|
|
|
|
static char *commands[] = {"BA","BR","IO","RT",
|
|
"D","M","B","T","LL","CT"};
|
|
static int commands_count = sizeof(commands)/sizeof(commands[0]);
|
|
|
|
static unsigned short a2l[0x10000]; // labels pointer;
|
|
static unsigned short p2a[0x10000];
|
|
static int labelptrs[0x10000];
|
|
static int maxptrs = 0;
|
|
|
|
static char labels[0x100000];
|
|
static int maxlabels = 0;
|
|
|
|
void moninit()
|
|
{
|
|
openscreen(SCR_ID_MONITOR);
|
|
}
|
|
|
|
char *getcmd(char *to, char *from)
|
|
{
|
|
int i,j,size = strlen(from);
|
|
|
|
*to = 0x00;
|
|
|
|
while (*from == 0x20)
|
|
*from++;
|
|
|
|
i = 0;
|
|
while (i<commands_count)
|
|
{
|
|
j = 0;
|
|
while ( (commands[i][j] == toupper(from[j])) && (j<size) )
|
|
{
|
|
j++;
|
|
}
|
|
if ((commands[i][j] == 0x00) && (j>0))
|
|
{
|
|
strcpy(to,commands[i]);
|
|
from += strlen(commands[i]);
|
|
break;
|
|
}
|
|
i++;
|
|
}
|
|
while (*from == 0x20)
|
|
*from++;
|
|
|
|
return from;
|
|
|
|
}
|
|
|
|
char *getstr(char *to, char *from, int flag)
|
|
{
|
|
if (flag == 0)
|
|
{
|
|
while (*from && (*from != ' '))
|
|
{
|
|
*to++ = toupper(*from++);
|
|
}
|
|
}
|
|
else if (flag == 1)
|
|
{
|
|
while (*from && (toupper(*from) >= 'A') && (toupper(*from) <= 'Z'))
|
|
{
|
|
*to++ = toupper(*from++);
|
|
}
|
|
}
|
|
else if (flag == 2)
|
|
{
|
|
while (*from && (*from != ' ') && (*from != ',') )
|
|
{
|
|
*to++ = toupper(*from++);
|
|
}
|
|
}
|
|
|
|
*to = 0;
|
|
|
|
while (*from == ' ')
|
|
from++;
|
|
|
|
return from;
|
|
}
|
|
|
|
void do_command(char *str)
|
|
{
|
|
char cmd[256];
|
|
char tempstring[256];
|
|
|
|
double tempdouble;
|
|
int from,to,val,qi;
|
|
|
|
str = getcmd(cmd,str);
|
|
|
|
// scrprintf(SCR_ID_MONITOR,"command: [%s] param: [%s]\n",cmd,str);
|
|
|
|
if (strcmp(cmd,"BR") == 0)
|
|
{
|
|
str = getstr(cmd,str,0);
|
|
if (*cmd)
|
|
{
|
|
calc(cmd, &tempdouble);
|
|
val = (int)tempdouble;
|
|
}
|
|
else
|
|
val = 0;
|
|
|
|
if ((val>=0) && (val<cpu.breakpoint_count))
|
|
{
|
|
for(from = val; from<cpu.breakpoint_count-1; from++)
|
|
{
|
|
cpu.breakpoints[from] = cpu.breakpoints[from+1];
|
|
}
|
|
cpu.breakpoints[cpu.breakpoint_count--] = 0;
|
|
scrprintf(SCR_ID_MONITOR,"Breakpoint %d removed\n",val);
|
|
}
|
|
}
|
|
else if (strcmp(cmd,"BA") == 0)
|
|
{
|
|
str = getstr(cmd,str,0);
|
|
sprintf(tempstring,"$%s",cmd);
|
|
calc(tempstring, &tempdouble);
|
|
|
|
if (cpu.breakpoint_count<32)
|
|
{
|
|
cpu.breakpoints[cpu.breakpoint_count] = ( ((int)tempdouble) & 0xffff ) | 0x10000;
|
|
scrprintf(SCR_ID_MONITOR,"Breakpoint %d set to $%04x\n", cpu.breakpoint_count, cpu.breakpoints[cpu.breakpoint_count++]);
|
|
}
|
|
}
|
|
else if (strcmp(cmd,"B") == 0)
|
|
{
|
|
val = 0;
|
|
for (qi=0; qi<cpu.breakpoint_count; qi++)
|
|
{
|
|
if (cpu.breakpoints[qi] >= 0x10000)
|
|
{
|
|
scrprintf(SCR_ID_MONITOR,"Breakpoint %d: $%04x ", qi, cpu.breakpoints[qi] & 0xffff);
|
|
if (cpu.breakpoints[qi] & 0x10000)
|
|
scrprintf(SCR_ID_MONITOR,"X");
|
|
else
|
|
scrprintf(SCR_ID_MONITOR," ");
|
|
|
|
if (cpu.breakpoints[qi] & 0x20000)
|
|
scrprintf(SCR_ID_MONITOR,"R");
|
|
else
|
|
scrprintf(SCR_ID_MONITOR," ");
|
|
|
|
if (cpu.breakpoints[qi] & 0x40000)
|
|
scrprintf(SCR_ID_MONITOR,"W");
|
|
else
|
|
scrprintf(SCR_ID_MONITOR," ");
|
|
|
|
scrprintf(SCR_ID_MONITOR," %s\n",getlabel(cpu.breakpoints[qi] & 0xffff));
|
|
val++;
|
|
}
|
|
}
|
|
if (!val)
|
|
scrprintf(SCR_ID_MONITOR,"No breakpoints set\n");
|
|
|
|
}
|
|
else if (strcmp(cmd,"T") == 0)
|
|
{
|
|
scrprintf(SCR_ID_MONITOR,"Total tick count: %d\n", cpu.ticks);
|
|
}
|
|
else if (strcmp(cmd,"RT") == 0)
|
|
{
|
|
cpu.ticks=0;
|
|
scrprintf(SCR_ID_MONITOR,"Total tick count reseted\n");
|
|
}
|
|
else if (strcmp(cmd,"D") == 0)
|
|
{
|
|
str = getstr(cmd,str,0);
|
|
sprintf(tempstring,"$%s",cmd);
|
|
calc(tempstring, &tempdouble);
|
|
from = ((int)tempdouble) & 0xffff;
|
|
|
|
str = getstr(cmd,str,0);
|
|
if (strlen(cmd)>0)
|
|
{
|
|
sprintf(tempstring,"$%s",cmd);
|
|
calc(tempstring, &tempdouble);
|
|
to = (int)tempdouble;
|
|
}
|
|
else
|
|
to += from + 0x20;
|
|
|
|
while (from<to)
|
|
{
|
|
from += getinst(tempstring,from);
|
|
scrprintf(SCR_ID_MONITOR,".%s\n",tempstring);
|
|
}
|
|
}
|
|
else if (strcmp(cmd,"IO") == 0)
|
|
{
|
|
str = getstr(cmd,str,2);
|
|
calc(cmd, &tempdouble);
|
|
from = ((int)tempdouble) & 0xff;
|
|
if (*str==',')
|
|
{
|
|
str = getstr(cmd,str+1,0);
|
|
calc(cmd, &tempdouble);
|
|
val = ((int)tempdouble) & 0xffff;
|
|
ioextender[from].input = val;
|
|
}
|
|
scrprintf(SCR_ID_MONITOR,"IO Expander %d\n Input: %04x Output: %04x\n", from, ioextender[from].input, ioextender[from].output);
|
|
}
|
|
else if (strcmp(cmd,"M") == 0)
|
|
{
|
|
str = getstr(cmd,str,0);
|
|
sprintf(tempstring,"$%s",cmd);
|
|
calc(tempstring, &tempdouble);
|
|
mempos = ((int)tempdouble) & 0xffff;
|
|
scrprintf(SCR_ID_MONITOR,"Memory dump address set to $%04x\n", mempos);
|
|
showmemory(mempos);
|
|
}
|
|
else if (strcmp(cmd,"LL") == 0)
|
|
{
|
|
str = getstr(cmd,str,0);
|
|
if (*cmd)
|
|
{
|
|
scrprintf(SCR_ID_MONITOR,"[%s]\n",cmd);
|
|
sprintf(tempstring,"0+%s",cmd);
|
|
calc(tempstring, &tempdouble);
|
|
from = (int)tempdouble;
|
|
}
|
|
else
|
|
from = 0;
|
|
|
|
if (from < 1)
|
|
from = 1;
|
|
|
|
for (qi = from; qi < from+25; qi++)
|
|
{
|
|
if (qi<maxptrs)
|
|
{
|
|
scrprintf(SCR_ID_MONITOR,"label %d: %s = $%04X\n",qi,&labels[labelptrs[qi]],p2a[qi]);
|
|
}
|
|
|
|
}
|
|
}
|
|
else if (strcmp(cmd,"CT") == 0)
|
|
{
|
|
str = getstr(cmd,str,0);
|
|
calc(cmd, &tempdouble);
|
|
from = (int)tempdouble;
|
|
|
|
if ((from>=0) && (from<MAX_DISPLAY))
|
|
{
|
|
if (screens[from] != NULL)
|
|
{
|
|
screens[from]->type ^= 1;
|
|
scrprintf(SCR_ID_MONITOR,"display %d mode changed to %d\n",from,screens[from]->type);
|
|
}
|
|
else
|
|
scrprintf(SCR_ID_MONITOR,"display %d not available\n",from);
|
|
}
|
|
else
|
|
{
|
|
scrprintf(SCR_ID_MONITOR,"invalid display id\n",from);
|
|
}
|
|
}
|
|
|
|
else if (*str)
|
|
{
|
|
scrprintf(SCR_ID_MONITOR,"Unknown command [%s]\n\n",cmd);
|
|
scrprintf(SCR_ID_MONITOR," B\t\tCheck breakpoint\n");
|
|
scrprintf(SCR_ID_MONITOR," BA xxxx\tAdd breakpoint\n");
|
|
scrprintf(SCR_ID_MONITOR," BR\t\tRemove breakpoint\n");
|
|
scrprintf(SCR_ID_MONITOR," D xxxx (yyyy)\tAssembly dump from $xxxx (to $yyyy)\n");
|
|
scrprintf(SCR_ID_MONITOR," IO x,(val)\tDump IO Expander number x (and set input to VALue)\n");
|
|
scrprintf(SCR_ID_MONITOR," M xxxx\t\tSet memory dump address to $xxxx\n");
|
|
scrprintf(SCR_ID_MONITOR," LL (x)\t\tList 25 labels (from element x)\n");
|
|
scrprintf(SCR_ID_MONITOR," CT (x)\t\tToggles display (id x) type (monochrome/color)\n\n");
|
|
}
|
|
}
|
|
|
|
int monitor()
|
|
{
|
|
int quit=0;
|
|
int esc=0;
|
|
int last_tick;
|
|
char tempstring[256];
|
|
char *ptr = tempstring;
|
|
|
|
sprintf(tempstring, "\rmonitor mode, hit ESC to exit");
|
|
drawstring(0, C_SIZEY-1, tempstring, 0x01, 0x00, rom_charset);
|
|
|
|
scrprintf(SCR_ID_MONITOR,"\n%s\n",tempstring);
|
|
|
|
*tempstring = 0;
|
|
|
|
while (!quit && !esc)
|
|
{
|
|
|
|
last_tick = timer_tick;
|
|
|
|
displayscreen(SCR_ID_MONITOR);
|
|
updateptc();
|
|
|
|
while (last_tick == timer_tick)
|
|
SDL_Delay(1);
|
|
|
|
while (getkeys())
|
|
{
|
|
if (lastkeysym >= 0)
|
|
{
|
|
if (lastkeysym == SDLK_ESCAPE)
|
|
esc = 1;
|
|
if ((lastkeysym == SDLK_x) && (lastkeymod & KMOD_ALT))
|
|
quit = 1; // alt-x
|
|
if ((lastkeysym == SDLK_F4) && (lastkeymod & KMOD_ALT))
|
|
quit = 1; // alt-f4
|
|
}
|
|
|
|
if (lastkey > 0)
|
|
{
|
|
if (lastkey>=0x20)
|
|
{
|
|
if (ptr<tempstring+79)
|
|
{
|
|
*ptr++ = lastkey;
|
|
*ptr = 0x00;
|
|
scrprintf(SCR_ID_MONITOR,"%c",lastkey);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (lastkey == 0x08)
|
|
{
|
|
if (ptr>tempstring)
|
|
*(--ptr) = 0x00;
|
|
scrprintf(SCR_ID_MONITOR,"%c",lastkey);
|
|
}
|
|
if ((lastkey == 13) || (lastkey == 10))
|
|
{
|
|
scrprintf(SCR_ID_MONITOR,"\n");
|
|
do_command(tempstring);
|
|
ptr = tempstring;
|
|
*tempstring = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (lastkey == -2)
|
|
quit = 1;
|
|
}
|
|
}
|
|
return quit;
|
|
}
|
|
|
|
void cleanstring(char *str)
|
|
{
|
|
char *dst = str;
|
|
while (*str)
|
|
{
|
|
if (*str >= 0x20)
|
|
*dst++ = *str;
|
|
*str++;
|
|
}
|
|
|
|
*dst = 0x00;
|
|
|
|
}
|
|
char *getlabelfromstr(char *label, char *line)
|
|
{
|
|
char *min = label;
|
|
|
|
while (*line == 0x20)
|
|
*line ++;
|
|
|
|
while ((*line != 0x00) && (*line != '='))
|
|
*label ++ = *line++;
|
|
|
|
while (*line == '=')
|
|
*line ++;
|
|
|
|
while ((label>min) && (*(label-1) == 0x20))
|
|
*label --;
|
|
|
|
*label = 0x00;
|
|
return line;
|
|
|
|
}
|
|
|
|
void monitor_listing(char *fname)
|
|
{
|
|
FILE *f;
|
|
char line[256];
|
|
char label[256];
|
|
char addr[256];
|
|
char *ptr;
|
|
double tempdouble;
|
|
int tempint;
|
|
|
|
if ((f = fopen(fname, "rb")) != NULL)
|
|
{
|
|
memset(&a2l, 0x00, sizeof(a2l));
|
|
memset(&p2a, 0x00, sizeof(p2a));
|
|
memset(&labels, 0x00, sizeof(labels));
|
|
memset(&labelptrs, 0x00, sizeof(labelptrs));
|
|
maxptrs = 0;
|
|
maxlabels = 1; // first is empty string;
|
|
|
|
printf("reading listing file: %s\n",fname);
|
|
while (!feof(f))
|
|
{
|
|
fgets(line, sizeof(line), f);
|
|
cleanstring(line);
|
|
if (*line)
|
|
{
|
|
ptr = getlabelfromstr(label,line);
|
|
|
|
while (*ptr == 0x20)
|
|
*ptr++;
|
|
|
|
ptr = getstr(addr,ptr,0);
|
|
calc(addr, &tempdouble);
|
|
tempint = (int)tempdouble;
|
|
// printf("label: %s addr: %04x\n",label,tempint);
|
|
|
|
if ((tempint) && (!a2l[tempint]))
|
|
{
|
|
a2l[tempint] = ++maxptrs;
|
|
p2a[maxptrs] = tempint;
|
|
strcpy(labels+maxlabels, label);
|
|
labelptrs[maxptrs] = maxlabels;
|
|
maxlabels += sizeof(label) + 1;
|
|
}
|
|
}
|
|
}
|
|
fclose(f);
|
|
}
|
|
else {
|
|
printf("listing file not found: %s\n",fname);
|
|
}
|
|
|
|
}
|
|
|
|
char *getlabel(int address)
|
|
{
|
|
if (a2l[address])
|
|
return labels + labelptrs[a2l[address]];
|
|
else
|
|
return labels;
|
|
}
|
|
|
|
int getaddress(char *label)
|
|
{
|
|
int qi = 1, found = 1;
|
|
while ((qi < maxptrs) && found)
|
|
{
|
|
found = strcasecmp(label,&labels[labelptrs[qi]]);
|
|
if (found) qi++;
|
|
}
|
|
if (!found)
|
|
return p2a[qi];
|
|
else
|
|
return -1;
|
|
} |