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

#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;
}