home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Source Code 1992 March
/
Source_Code_CD-ROM_Walnut_Creek_March_1992.iso
/
usenet
/
altsrcs
/
2
/
2037
/
udbg.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-12-28
|
10KB
|
502 lines
/*
debug.c - debugger for z-80 emulator.
*/
#include <stdio.h>
#include <setjmp.h>
#include <signal.h>
#include "z80.h"
extern char *sys_errlist[];
extern int errno;
jmp_buf lj;
void int_handler()
{
longjmp(lj);
}
long z80_memlines[65536];
long z80_memseeks[65536];
FILE *z80_file;
#include <sgtty.h>
extern struct sgttyb tty_sgtty_data;
debug_write(x,y)
WORD x;
BYTE y;
{
if(x==TWRTval) { /* bdos storage of user # == 0xedfe*/
printf("\n\r0x%04x:%02x\n\r",x,y);
debugit();
}
real_z80_mem[x]=y;
}
debugit()
{
int i;
gtty(fileno(stdin),&tty_sgtty_data);
tty_sgtty_data.sg_flags&=~RAW;
tty_sgtty_data.sg_flags|=ECHO;
stty(fileno(stdin),&tty_sgtty_data);
z80_file = 0;
while(1)
{
char ibuf[128], *istat;
char cmd_char;
do {
printf("\n>");
bzero(ibuf,127);
istat = fgets(ibuf, 127, stdin);
} while (istat && strlen(ibuf)<2);
if(!istat) break;
cmd_char = ibuf[0];
switch(cmd_char)
{
case 'd':dump(ibuf);
break;
case 'G':/* z80_run(ibuf) */
gtty(fileno(stdin),&tty_sgtty_data);
tty_sgtty_data.sg_flags|=RAW;
tty_sgtty_data.sg_flags&=~ECHO;
stty(fileno(stdin),&tty_sgtty_data);
return 1;
case 'g':/* z80_run(ibuf) */
gtty(fileno(stdin),&tty_sgtty_data);
tty_sgtty_data.sg_flags|=RAW;
tty_sgtty_data.sg_flags&=~ECHO;
stty(fileno(stdin),&tty_sgtty_data);
return 0;
break;
case 's':z80_instr(ibuf);
/* break; */ /* really fall through */
case 'c':pr_reg(ibuf);
break;
case 'l':gethex(ibuf);
break;
case 'b':getbin(ibuf);
break;
case 'm':movemem(ibuf);
break;
case 'w':writehex(ibuf);
break;
case 'y':getlines(ibuf);
break;
case 'r':set_reg(ibuf);
break;
case 'q':
gtty(fileno(stdin),&tty_sgtty_data);
tty_sgtty_data.sg_flags|=RAW;
tty_sgtty_data.sg_flags&=~ECHO;
stty(fileno(stdin),&tty_sgtty_data);
exit(0);
break;
case 'e':edit(ibuf);
break;
case '$':user_cmd(ibuf);
break;
default:help(ibuf);
break;
}
}
}
/*
on-line help
*/
help(ibuf) char* ibuf;
{
printf("\nb file - load a binary image\n");
printf("c - display register values\n");
printf("d start [len] - display memory\n");
printf("e start - edit memory\n");
printf("g - start Z-80 running\n");
printf("l file - load hex file\n");
printf("m start end dest - move a chunk of memory\n");
printf("q - quit\n");
printf("r reg val - change register/flag value\n");
printf("s - single step\n");
printf("w start end file - write hex file\n");
printf("y file - read lines file\n");
printf("$ - execute user command\n");
}
/*
dump
*/
dump(ibuf) char* ibuf;
{
int start,end=0;
if(2!=sscanf(ibuf,"%*s %x %x",&start,&end)) {
printf("usage: dump start end\n");
return;
}
pr_mem(start,end);
}
/*
edit
*/
edit(ibuf) char* ibuf;
{
int start,byte;
if(2!=sscanf(ibuf,"%*s %x %x",&start,&byte)) {
printf("usage: edit address value\n");
return;
}
start&=0xffff;
byte&=0xff;
real_z80_mem[start]=byte;
}
/*
set registers
*/
set_reg(ibuf) char* ibuf;
{
char reg[80];
int i;
if(2!=sscanf(ibuf,"%*s %s %x",reg, &i)) {
printf("usage: set register value\n");
return;
}
i&=0xffff;
if (!strcmp(reg,"pc"))
PC=i;
else if (!strcmp(reg,"sp"))
SP=i;
else if (!strcmp(reg,"af"))
AF=i;
else if (!strcmp(reg,"bc"))
BC=i;
else if (!strcmp(reg,"de"))
DE=i;
else if (!strcmp(reg,"hl"))
HL=i;
else if (!strcmp(reg,"af'"))
AF2=i;
else if (!strcmp(reg,"bc'"))
BC2=i;
else if (!strcmp(reg,"de'"))
DE2=i;
else if (!strcmp(reg,"hl'"))
HL2=i;
else if (!strcmp(reg,"ix"))
IX=i;
else if (!strcmp(reg,"iy"))
IY=i;
else if (!strcmp(reg,"i"))
IR=(IR&0xff)|(i<<8);
else if (!strcmp(reg,"r"))
IR=(IR&0xff00)|i;
else {
printf("register should be one of: pc sp af bc de hl af' bc' de' hl' ix iy i r\n");
}
}
/*
dump out memory for the user. A is the starting address. L is the amount
of dumping he wants. if L is 0, a default value is supplied.
*/
pr_mem(a,l)
WORD a,l;
{
WORD i;
int counter=0;
if (!l)
l=0x100;
for(i=0;i<l;i++)
{
if (!(counter%16))
printf("%04X- ",(a+i)&0xffff);
printf("%02X ",real_z80_mem[(a+i)&0xffff]);
counter++;
if (!(counter%16))
{
char c; int j;
for (j=15;j>=0;j--)
{
c=real_z80_mem[(a+i-j)&0xffff]&0x7f;
putchar( ((c>0x20) && (c<0x7f))?c:'.' );
}
printf("\n");
}
}
if (counter%16)
{
int j;
char c;
for(j=counter%16;j>0;j--)
{
c=real_z80_mem[(a+i-j)&0xffff]&0x7f;
putchar( ((c>0x20) && (c<0x7f))?c:'.' );
}
printf("\n");
}
}
show_debug_line(addr) WORD addr;
{
char ibuf[1024];
int ilow = addr, ihi = addr;
if(z80_file) {
while(ilow>0 && !z80_memlines[ilow]) ilow--;
while(ihi<65536 && !z80_memlines[ilow]) ihi++;
printf("(range %d %d)\n",ilow,ihi);
fseek(z80_file,z80_memseeks[ilow],0);
fgets(ibuf,1023,z80_file);
printf("%d: %s",z80_memlines[ilow],ibuf); /* \n included in ibuf... */
}
}
pr_reg(ibuf) char* ibuf;
{
static char *flag_chars="CNVxHxZS";
int i;
printf("\nA =%02XH BC =%04XH DE =%04XH HL =%04XH SP=%04XH IX=%04XH\n"
,AF>>8,BC,DE,HL,SP,IX);
printf("A'=%02XH BC'=%04XH DE'=%04XH HL'=%04XH PC=%04XH IY=%04XH\n"
,AF2>>8,BC2,DE2,HL2,PC,IY);
printf("\nI=%02XH R=%02XH F=",IR>>8,IR%0xff);
for(i=7;i>=0;i--)
putchar( (AF&(1<<i))?flag_chars[i]:'-' );
printf(" F'=");
for(i=7;i>=0;i--)
putchar( (AF2&(1<<i))?flag_chars[i]:'-' );
printf(" IFF1=%c IFF2=%c"
,(INT_FLAGS&IFF1)?'1':'-',(INT_FLAGS&IFF2)?'1':'-');
printf("\n(PC)=");
for(i=PC; i<PC+16; i++) {
printf("%02X ",real_z80_mem[i]);
}
printf("\n(HL)=");
for(i=HL; i<HL+16; i++) {
printf("%02X ",real_z80_mem[i]);
}
printf("\n(SP)=");
for(i=SP; i<SP+16; i++) {
printf("%02X ",real_z80_mem[i]);
}
printf("\n");
show_debug_line(PC);
}
getlines(ibuf) char* ibuf;
{
char fname[80];
char lbuf[1024], *lstat;
if(z80_file) {
int i;
fclose(z80_file);
for(i = 0; i<65536; i++) {
z80_memlines[i] = 0;
z80_memseeks[i] = 0;
}
}
sscanf(ibuf,"%*s %s",fname);
z80_file=fopen(fname,"r");
if (z80_file==NULL)
{
printf("%s: %s",fname,sys_errlist[errno]);
return;
}
/* long z80_memlines[65536]; */
do {
int addr, line, told;
told = ftell(z80_file);
lstat = fgets(lbuf, 1023, z80_file);
if(!lstat) break;
sscanf(lbuf,"%d: %x",&line,&addr);
z80_memlines[addr] = line;
z80_memseeks[addr] = told;
} while(lstat);
/* fclose(file); */
}
gethex(ibuf) char* ibuf;
{
char fname[80];
FILE *file;
sscanf(ibuf,"%*s %s",fname);
file=fopen(fname,"r");
if (file==NULL)
{
printf("%s: %s",fname,sys_errlist[errno]);
return;
}
loadhex(file);
fclose(file);
}
getbin(ibuf) char* ibuf;
{
char fname[80];
FILE *file;
WORD icount=0,count=0;
if(2!=sscanf(ibuf,"%*s %hx %s",&icount,fname)) {
printf("usage: getbin offset filename\n");
return;
};
file=fopen(fname,"r");
if (file==NULL)
{
printf("%s: %s",fname,sys_errlist[errno]);
return;
}
count=icount;
printf("loading %s into %04x\n",fname,count);
while (!feof(file))
real_z80_mem[count++]=getc(file);
fclose(file);
printf("loaded %d bytes (save %d foo.com)\n",count-icount,((count-icount)/256)+1);
}
extern BYTE csum();
/*
#define HEXCHAR(a) ( ((a)>=10) ? ((a)+'a'-10) : ((a)+'0') )
*/
char HEXCHAR(a)
char a;
{
return ( ((a)>=10) ? ((a)+'a'-10) : ((a)+'0') );
}
writehex(ibuf) char* ibuf;
{
char fname[80],c[80];
FILE *file;
WORD start,end,i,j;
BYTE tmp;
char counter=0;
if(3!=sscanf(ibuf,"%*s %hx %hx %s",&start,&end,fname)) {
printf("usage: write start end filename\n");
return;
}
end++;
file=fopen(fname,"a");
if (file==NULL)
{
printf("%s: %s",fname,sys_errlist[errno]);
return;
}
for(i=start;i<=end-32;i+=32)
{
strcpy(c,":20");
c[3]=HEXCHAR(i>>12);
c[4]=HEXCHAR((i>>8)&15);
c[5]=HEXCHAR((i>>4)&15);
c[6]=HEXCHAR(i&15);
c[7]='0';
c[8]='0';
for(j=0;j<32;j++)
{
c[ 9+2*j]=HEXCHAR(real_z80_mem[i+j]>>4);
c[10+2*j]=HEXCHAR(real_z80_mem[i+j]&15);
}
c[73]=0;
tmp=256-csum(c+1);
c[73]=HEXCHAR(tmp>>4);
c[74]=HEXCHAR(tmp&15);
c[75]=0;
fprintf(file,"%s\n",c);
}
if (i<end)
{
c[1]=HEXCHAR((end-i)>>4);
c[2]=HEXCHAR((end-i)&15);
c[3]=HEXCHAR(i>>12);
c[4]=HEXCHAR((i>>8)&15);
c[5]=HEXCHAR((i>>4)&15);
c[6]=HEXCHAR(i&15);
c[7]='0';
c[8]='0';
for (j=0;j<end-i;j++)
{
c[ 9+2*j]=HEXCHAR(real_z80_mem[i+j]>>4);
c[10+2*j]=HEXCHAR(real_z80_mem[i+j]&15);
}
c[ 9+2*(end-i)]=0;
tmp=256-csum(c+1);
c[ 9+2*(end-i)]=HEXCHAR(tmp>>4);
c[10+2*(end-i)]=HEXCHAR(tmp&15);
c[11+2*(end-i)]=0;
fprintf(file,"%s\n",c);
}
fprintf(file,":0000000000\n");
fclose(file);
}
movemem(ibuf) char* ibuf;
{
WORD start,end,new,i;
if(3!=sscanf(ibuf,"%*s %hx %hx %hx",&start,&end,&new)) {
printf("usage: move old_start old_end new_start\n");
return;
}
for(i=start;i<=end;i++)
real_z80_mem[new+(i-start)]=real_z80_mem[i];
}
user_cmd(ibuf) char* ibuf; /* for us, a relocator */
{
WORD start,end,bitmap,offset,i;
if(4!=sscanf(ibuf,"%*s %hx %hx %hx %hx",&start,&end,&bitmap,&offset)) {
printf("usage: user_cmd start end bitmap offset\n");
return;
}
offset&=0xff;
for (i=start;i<=end;i++)
if ( real_z80_mem[bitmap+((i-start)/8)] & (1<<((i-start)%8)) )
real_z80_mem[i]+=offset;
}