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