home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 2 / 2037 / debug.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-12-28  |  8.4 KB  |  460 lines

  1. /*
  2.  
  3. debug.c - debugger for z-80 emulator.
  4.  
  5. */
  6.  
  7. #include <stdio.h>
  8. #include <setjmp.h>
  9. #include <signal.h>
  10.  
  11. #include "z80.h"
  12. extern char *sys_errlist[];
  13. extern int errno;
  14.  
  15. jmp_buf lj;
  16.  
  17. void int_handler()
  18. {
  19.   longjmp(lj);
  20. }
  21.  
  22. long z80_memlines[65536];
  23. long z80_memseeks[65536];
  24. FILE *z80_file;
  25.  
  26.  
  27.  
  28. main()
  29. {
  30.   int i;
  31.  
  32.   setjmp(lj);
  33.   signal(SIGINT,int_handler);
  34.  
  35.   z80_file = 0;
  36.   while(1)
  37.   {
  38.     char ibuf[128], *istat;
  39.     
  40.     char cmd_char;
  41.  
  42.     do {
  43.       printf("\n>");
  44.       bzero(ibuf,127);
  45.       istat = fgets(ibuf, 127, stdin);
  46.     } while (istat && strlen(ibuf)<2);
  47.     if(!istat) break;
  48.     
  49.     cmd_char = ibuf[0];
  50.     switch(cmd_char)
  51.     {
  52.     case 'd':dump(ibuf);
  53.     break;
  54.     case 's':z80_instr(ibuf);
  55.     break;
  56.     case 'g':z80_run(ibuf);
  57.     break;
  58.     case 'c':pr_reg(ibuf);
  59.     break;
  60.     case 'l':gethex(ibuf);
  61.     break;
  62.     case 'b':getbin(ibuf);
  63.     break;
  64.     case 'm':movemem(ibuf);
  65.     break;
  66.     case 'w':writehex(ibuf);
  67.     break;
  68.     case 'y':getlines(ibuf);
  69.     break;
  70.     case 'r':set_reg(ibuf);
  71.     break;
  72.     case 'q':exit(0);
  73.     break;
  74.     case 'e':edit(ibuf);
  75.     break;
  76.     case '$':user_cmd(ibuf);
  77.     break;
  78.     default:help(ibuf);
  79.     break;
  80.     }
  81.   }
  82.  
  83. }
  84.  
  85. /*
  86.  
  87. on-line help
  88.  
  89. */
  90.  
  91. help(ibuf) char* ibuf;
  92. {
  93.   printf("\nb file           - load a binary image\n");
  94.   printf("c                - display register values\n");
  95.   printf("d start [len]    - display memory\n");
  96.   printf("e start          - edit memory\n");
  97.   printf("g                - start Z-80 running\n");
  98.   printf("l file           - load hex file\n");
  99.   printf("m start end dest - move a chunk of memory\n");
  100.   printf("q                - quit\n");
  101.   printf("r reg val        - change register/flag value\n");
  102.   printf("s                - single step\n");
  103.   printf("w start end file - write hex file\n");
  104.   printf("y file           - read lines file\n");
  105.   printf("$                - execute user command\n");
  106. }
  107.  
  108. /*
  109.  
  110. dump
  111.  
  112. */
  113.  
  114. dump(ibuf) char* ibuf;
  115. {
  116.   int start,end=0;
  117.  
  118.   if(2!=sscanf(ibuf,"%*s %x %x",&start,&end)) {
  119.     printf("usage: dump start end\n");
  120.     return;
  121.   }
  122.   pr_mem(start,end);
  123. }
  124.  
  125. /*
  126.  
  127. edit
  128.  
  129. */
  130.  
  131. edit(ibuf) char* ibuf;
  132. {
  133.   int start,byte;
  134.   if(2!=sscanf(ibuf,"%*s %x %x",&start,&byte)) {
  135.     printf("usage: edit address value\n");
  136.     return;
  137.   }
  138.   start&=0xffff;
  139.   byte&=0xff;
  140.   real_z80_mem[start]=byte;
  141. }
  142.  
  143. /*
  144.  
  145. set registers
  146.  
  147. */
  148.  
  149. set_reg(ibuf) char* ibuf;
  150. {
  151.   char reg[80];
  152.   int i;
  153.   if(2!=sscanf(ibuf,"%*s %s %x",reg, &i)) {
  154.     printf("usage: set register value\n");
  155.     return;
  156.   }
  157.   i&=0xffff;
  158.   if (!strcmp(reg,"pc"))
  159.     PC=i;
  160.   else if (!strcmp(reg,"sp"))
  161.     SP=i;
  162.   else if (!strcmp(reg,"af"))
  163.     AF=i;
  164.   else if (!strcmp(reg,"bc"))
  165.     BC=i;
  166.   else if (!strcmp(reg,"de"))
  167.     DE=i;
  168.   else if (!strcmp(reg,"hl"))
  169.     HL=i;
  170.   else if (!strcmp(reg,"af'"))
  171.     AF2=i;
  172.   else if (!strcmp(reg,"bc'"))
  173.     BC2=i;
  174.   else if (!strcmp(reg,"de'"))
  175.     DE2=i;
  176.   else if (!strcmp(reg,"hl'"))
  177.     HL2=i;
  178.   else if (!strcmp(reg,"ix"))
  179.     IX=i;
  180.   else if (!strcmp(reg,"iy"))
  181.     IY=i;
  182.   else if (!strcmp(reg,"i"))
  183.     IR=(IR&0xff)|(i<<8);
  184.   else if (!strcmp(reg,"r"))
  185.     IR=(IR&0xff00)|i;
  186.   else {
  187.     printf("register should be one of: pc sp af bc de hl af' bc' de' hl' ix iy i r\n");
  188.   }
  189. }
  190.  
  191. /*
  192.  
  193. dump out memory for the user. A is the starting address. L is the amount
  194. of dumping he wants. if L is 0, a default value is supplied.
  195.  
  196. */
  197.  
  198. pr_mem(a,l)
  199. WORD a,l;
  200. {
  201.   WORD i;
  202.   int counter=0;
  203.  
  204.   if (!l)
  205.     l=0x100;
  206.   for(i=0;i<l;i++)
  207.   {
  208.     if (!(counter%16))
  209.       printf("%04X- ",(a+i)&0xffff);
  210.  
  211.     printf("%02X ",real_z80_mem[(a+i)&0xffff]);
  212.     counter++;
  213.  
  214.     if (!(counter%16))
  215.     {
  216.       char c,j;
  217.       for (j=15;j>=0;j--)
  218.       {
  219.     c=real_z80_mem[(a+i-j)&0xffff]&0x7f;
  220.         putchar( ((c>0x20) && (c<0x7f))?c:'.' );
  221.       }
  222.       printf("\n");
  223.     }
  224.   }
  225.   if (counter%16)
  226.   {
  227.     int j;
  228.     char c;
  229.     for(j=counter%16;j>0;j--)
  230.     {
  231.       c=real_z80_mem[(a+i-j)&0xffff]&0x7f;
  232.       putchar( ((c>0x20) && (c<0x7f))?c:'.' );
  233.     }
  234.     printf("\n");
  235.   }
  236. }
  237.  
  238. show_debug_line(addr) WORD addr;
  239. {
  240.   char ibuf[1024];
  241.   int ilow = addr, ihi = addr;
  242.   if(z80_file) {
  243.     while(ilow>0 && !z80_memlines[ilow]) ilow--;
  244.     while(ihi<65536 && !z80_memlines[ilow]) ihi++;
  245.     printf("(range %d %d)\n",ilow,ihi);
  246.     fseek(z80_file,z80_memseeks[ilow],0);
  247.     fgets(ibuf,1023,z80_file);
  248.     printf("%d: %s",z80_memlines[ilow],ibuf); /* \n included in ibuf... */
  249.   }
  250. }
  251.  
  252. pr_reg(ibuf) char* ibuf;
  253. {
  254.   static char *flag_chars="CNVxHxZS";
  255.   int i;
  256.  
  257.   printf("\nA =%02XH BC =%04XH DE =%04XH HL =%04XH SP=%04XH IX=%04XH\n"
  258.       ,AF>>8,BC,DE,HL,SP,IX);
  259.   printf("A'=%02XH BC'=%04XH DE'=%04XH HL'=%04XH PC=%04XH IY=%04XH\n"
  260.       ,AF2>>8,BC2,DE2,HL2,PC,IY);
  261.  
  262.   printf("\nI=%02XH R=%02XH  F=",IR>>8,IR%0xff);
  263.   for(i=7;i>=0;i--)
  264.     putchar( (AF&(1<<i))?flag_chars[i]:'-' );
  265.   printf(" F'=");
  266.   for(i=7;i>=0;i--)
  267.     putchar( (AF2&(1<<i))?flag_chars[i]:'-' );
  268.   printf("  IFF1=%c  IFF2=%c"
  269.       ,(INT_FLAGS&IFF1)?'1':'-',(INT_FLAGS&IFF2)?'1':'-');
  270.  
  271.   printf("\n(PC)=");
  272.   for(i=PC; i<PC+16; i++) {
  273.     printf("%02X ",real_z80_mem[i]);
  274.   }
  275.   printf("\n(HL)=");
  276.   for(i=HL; i<HL+16; i++) {
  277.     printf("%02X ",real_z80_mem[i]);
  278.   }
  279.   printf("\n");
  280.  
  281.   show_debug_line(PC);
  282. }
  283.  
  284. getlines(ibuf) char* ibuf;
  285. {
  286.   char fname[80];
  287.   char lbuf[1024], *lstat;
  288.  
  289.   if(z80_file) {
  290.     int i;
  291.     fclose(z80_file);
  292.     for(i = 0; i<65536; i++) {
  293.       z80_memlines[i] = 0;
  294.       z80_memseeks[i] = 0;
  295.     }
  296.   }
  297.   sscanf(ibuf,"%*s %s",fname);
  298.  
  299.   z80_file=fopen(fname,"r");
  300.   if (z80_file==NULL)
  301.   {
  302.     printf("%s: %s",fname,sys_errlist[errno]);
  303.     return;
  304.   }
  305.   /* long z80_memlines[65536]; */
  306.   do {
  307.     int addr, line, told;
  308.     told = ftell(z80_file);
  309.     lstat = fgets(lbuf, 1023, z80_file);
  310.     if(!lstat) break;
  311.     sscanf(lbuf,"%d: %x",&line,&addr);
  312.     z80_memlines[addr] = line;
  313.     z80_memseeks[addr] = told;
  314.   } while(lstat);
  315.  
  316.   /* fclose(file); */
  317. }
  318.  
  319.  
  320. gethex(ibuf) char* ibuf;
  321. {
  322.   char fname[80];
  323.   FILE *file;
  324.  
  325.   sscanf(ibuf,"%*s %s",fname);
  326.  
  327.   file=fopen(fname,"r");
  328.   if (file==NULL)
  329.   {
  330.     printf("%s: %s",fname,sys_errlist[errno]);
  331.     return;
  332.   }
  333.   loadhex(file);
  334.   fclose(file);
  335. }
  336.  
  337. getbin(ibuf) char* ibuf;
  338. {
  339.   char fname[80];
  340.   FILE *file;
  341.   WORD count=0;
  342.  
  343.   sscanf(ibuf,"%*s %s",fname);
  344.  
  345.   file=fopen(fname,"r");
  346.   if (file==NULL)
  347.   {
  348.     printf("%s: %s",fname,sys_errlist[errno]);
  349.     return;
  350.   }
  351.   while (!feof(file))
  352.     real_z80_mem[count++]=getc(file);
  353.   fclose(file);
  354. }
  355.  
  356. extern BYTE csum();
  357. /*
  358. #define HEXCHAR(a) ( ((a)>=10) ? ((a)+'a'-10) : ((a)+'0') )
  359. */
  360. char HEXCHAR(a)
  361. char a;
  362. {
  363.   return ( ((a)>=10) ? ((a)+'a'-10) : ((a)+'0') );
  364. }
  365. writehex(ibuf) char* ibuf;
  366. {
  367.   char fname[80],c[80];
  368.   FILE *file;
  369.   WORD start,end,i,j;
  370.   BYTE tmp;
  371.   char counter=0;
  372.  
  373.   if(3!=sscanf(ibuf,"%*s %hx %hx %s",&start,&end,fname)) {
  374.     printf("usage: write start end filename\n");
  375.     return;
  376.   }
  377.   end++;
  378.  
  379.   file=fopen(fname,"a");
  380.   if (file==NULL)
  381.   {
  382.     printf("%s: %s",fname,sys_errlist[errno]);
  383.     return;
  384.   }
  385.   for(i=start;i<=end-32;i+=32)
  386.   {
  387.     strcpy(c,":20");
  388.     c[3]=HEXCHAR(i>>12);
  389.     c[4]=HEXCHAR((i>>8)&15);
  390.     c[5]=HEXCHAR((i>>4)&15);
  391.     c[6]=HEXCHAR(i&15);
  392.     c[7]='0';
  393.     c[8]='0';
  394.     for(j=0;j<32;j++)
  395.     {
  396.       c[ 9+2*j]=HEXCHAR(real_z80_mem[i+j]>>4);
  397.       c[10+2*j]=HEXCHAR(real_z80_mem[i+j]&15);
  398.     }
  399.     c[73]=0;
  400.     tmp=256-csum(c+1);
  401.     c[73]=HEXCHAR(tmp>>4);
  402.     c[74]=HEXCHAR(tmp&15);
  403.     c[75]=0;
  404.     fprintf(file,"%s\n",c);
  405.   }
  406.   if (i<end)
  407.   {
  408.     c[0]=':';
  409.     c[1]=HEXCHAR((end-i)>>4);
  410.     c[2]=HEXCHAR((end-i)&15);
  411.     c[3]=HEXCHAR(i>>12);
  412.     c[4]=HEXCHAR((i>>8)&15);
  413.     c[5]=HEXCHAR((i>>4)&15);
  414.     c[6]=HEXCHAR(i&15);
  415.     c[7]='0';
  416.     c[8]='0';
  417.     for (j=0;j<end-i;j++)
  418.     {
  419.       c[ 9+2*j]=HEXCHAR(real_z80_mem[i+j]>>4);
  420.       c[10+2*j]=HEXCHAR(real_z80_mem[i+j]&15);
  421.     }
  422.     c[ 9+2*(end-i)]=0;
  423.     tmp=256-csum(c+1);
  424.     c[ 9+2*(end-i)]=HEXCHAR(tmp>>4);
  425.     c[10+2*(end-i)]=HEXCHAR(tmp&15);
  426.     c[11+2*(end-i)]=0;
  427.     fprintf(file,"%s\n",c);
  428.   }
  429.   fprintf(file,":0000000000\n");
  430.   fclose(file);
  431. }
  432.  
  433. movemem(ibuf) char* ibuf;
  434. {
  435.   WORD start,end,new,i;
  436.  
  437.   if(3!=sscanf(ibuf,"%*s %hx %hx %hx",&start,&end,&new)) {
  438.     printf("usage: move old_start old_end new_start\n");
  439.     return;
  440.   }
  441.  
  442.   for(i=start;i<=end;i++)
  443.     real_z80_mem[new+(i-start)]=real_z80_mem[i];
  444. }
  445.  
  446. user_cmd(ibuf) char* ibuf; /* for us, a relocator */
  447. {
  448.   WORD start,end,bitmap,offset,i;
  449.  
  450.   if(4!=sscanf(ibuf,"%*s %hx %hx %hx %hx",&start,&end,&bitmap,&offset)) {
  451.     printf("usage: user_cmd start end bitmap offset\n");
  452.     return;
  453.   }
  454.   offset&=0xff;
  455.  
  456.   for (i=start;i<=end;i++)
  457.     if ( real_z80_mem[bitmap+((i-start)/8)] & (1<<((i-start)%8)) )
  458.       real_z80_mem[i]+=offset;
  459. }
  460.