home *** CD-ROM | disk | FTP | other *** search
/ Amiga Developer CD 2.1 / Amiga Developer CD v2.1.iso / Reference / DevCon / Washington_1988 / DevCon88.1 / JimmDemos / DemoSource / dcop.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-08-27  |  8.8 KB  |  384 lines

  1. /* copper.c -- copper list disassembly
  2.  *
  3.  * This is an enhanced version of a Copper List Disassembler
  4.  * Routine by Scott Evernden, 10/14/86, enhancements by
  5.  * Jim Mackraz and I and I Computing.
  6.  *
  7.  * This program is in the public domain.
  8.  *
  9.  * When using Aztec C compiler, use "cc -z3000" because
  10.  * of all the strings.
  11.  */
  12. /* magic z macro:  >%<<%<< */
  13.  
  14. #include "sysall.h"
  15.  
  16. #include "getargs.h"
  17.  
  18. /* needs to be updates real soon now    */
  19. static char *names[] = {
  20.     "bltddat","dmaconr","vposr","vhposr","dskdatr",
  21.     "joy0dat","joy1dat","clxdat","adkconr",
  22.     "pot0dat","pot1dat","potinp","serdatr","dskbytr",
  23.     "intenar","intreqr","dskpt","dskpt+2","dsklen","dskdat",
  24.     "refptr","vposw","vhposw","copcon","serdat","serper",
  25.     "potgo","joytest","strequ","strvbl","strhor","strlong",
  26.     "bltcon0","bltcon1","bltafwm","bltalwm",
  27.     "bltcpt","bltcpt+2","bltbpt","bltbpt+2",
  28.     "bltapt","bltapt+2","bltdpt","bltdpt+2",
  29.     "bltsize","pad2d[0]","pad2d[1]","pad2d[2]",
  30.     "bltcmod","bltbmod","bltamod","bltdmod",
  31.     "pad34[0]","pad34[1]","pad34[2]","pad34[3]",
  32.     "bltcdat","bltbdat","bltadat",
  33.     "pad3b[0]","pad3b[1]","pad3b[2]","pad3b[3]","dsksync",
  34.     "cop1lc","cop1lc+2","cop2lc","cop2lc+2","copjmp1","copjmp2",
  35.     "copins","diwstrt","diwstop","ddfstrt","ddfstop",
  36.     "dmacon","clxcon","intena","intreq","adkcon",
  37.     "aud[0].ac_ptr","aud[0].ac_ptr+2",
  38.     "aud[0].ac_len","aud[0].ac_per","aud[0].ac_vol","aud[0].ac_dat",
  39.     "aud[0].ac_pad[0]","aud[0].ac_pad[1]",
  40.     "aud[1].ac_ptr","aud[1].ac_ptr+2",
  41.     "aud[1].ac_len","aud[1].ac_per","aud[1].ac_vol","aud[1].ac_dat",
  42.     "aud[1].ac_pad[0]","aud[1].ac_pad[1]",
  43.     "aud[2].ac_ptr","aud[2].ac_ptr+2",
  44.     "aud[2].ac_len","aud[2].ac_per","aud[2].ac_vol","aud[2].ac_dat",
  45.     "aud[2].ac_pad[0]","aud[2].ac_pad[1]",
  46.     "aud[3].ac_ptr","aud[3].ac_ptr+2",
  47.     "aud[3].ac_len","aud[3].ac_per","aud[3].ac_vol","aud[3].ac_dat",
  48.     "aud[3].ac_pad[0]","aud[3].ac_pad[1]",
  49.  
  50.     "bpl1pth","bpl1ptl","bpl2pth","bpl2ptl",
  51.     "bpl3pth","bpl3ptl","bpl4pth","bpl4ptl",
  52.     "bpl5pth","bpl5ptl","bpl6pth","bpl6ptl",
  53.  
  54.     "pad7c[0]","pad7c[1]","pad7c[2]","pad7c[3]",
  55.  
  56.     "bplcon0","bplcon1","bplcon2","pad83",
  57.     "bpl1mod","bpl2mod","pad86[0]","pad86[1]",
  58.  
  59.     "bpl1dat","bpl2dat","bpl3dat","bpl4dat",
  60.     "bpl5dat","bpl6dat","pad8e[0]","pad8e[1]",
  61.  
  62.     "spr0pth","spr0ptl","spr1pth","spr1ptl",
  63.     "spr2pth","spr2ptl","spr3pth","spr3ptl",
  64.     "spr4pth","spr4ptl","spr5pth","spr5ptl",
  65.     "spr6pth","spr6ptl","spr7pth","spr7ptl",
  66.  
  67.     "spr0pos","spr0ctl","spr0data","spr0datb",
  68.     "spr1pos","spr1ctl","spr1data","spr1datb",
  69.     "spr2pos","spr2ctl","spr2data","spr2datb",
  70.     "spr3pos","spr3ctl","spr3data","spr3datb",
  71.     "spr4pos","spr4ctl","spr4data","spr4datb",
  72.     "spr5pos","spr5ctl","spr5data","spr5datb",
  73.     "spr6pos","spr6ctl","spr6data","spr6datb",
  74.     "spr7pos","spr7ctl","spr7data","spr7datb",
  75.  
  76.     "color0","color1","color2","color3",
  77.     "color4","color5","color6","color7",
  78.     "color8","color9","color10","color11",
  79.     "color12","color13","color14","color15",
  80.     "color16","color17","color18","color19",
  81.     "color20","color21","color22","color23",
  82.     "color24","color25","color26","color27",
  83.     "color28","color29","color30","color31"
  84. };
  85.  
  86. #define MAXNAME (((sizeof (names))/sizeof (char *)) - 1)
  87. char    noname[24];
  88.  
  89. char *
  90. regname( indx )
  91. {
  92.     if (indx > MAXNAME)
  93.     {
  94.         sprintf( noname, "<<no name: %x>>", indx);
  95.         return (noname);
  96.     }
  97.     else
  98.     {
  99.          return (names[indx]);
  100.     } 
  101. }
  102.  
  103. extern struct GfxBase    *GfxBase = NULL;
  104.  
  105. /* command line switches */
  106. int    all_bool = 0;        /* if true, do color tables, too */
  107. int    intermed_bool = 0;    /* do view port intermed. copps    */
  108. int    header_bool = 0;    /* do hardware header list    */
  109. int    hardware_bool = 0;    /* default: hardware lists    */
  110.  
  111. struct Arg myargs[] = {
  112.     {'a', ARG_TBOOL, &all_bool, "all: color tables incl."},
  113.     {'i', ARG_TBOOL, &intermed_bool, "vp intermediate lists"},
  114.     {'h', ARG_TBOOL, &header_bool, "gfx hardware list header"},
  115.     {'v', ARG_TBOOL, &hardware_bool, "view hardware lists (default)"},
  116. };
  117.  
  118. main(argc, argv)
  119. char    **argv;
  120. {
  121.     struct View    *view;
  122.     struct ViewPort *vp;
  123.  
  124.     int        all = TRUE;
  125.     int        default_work = 1;    /* default do hardware lists    */
  126.  
  127.     GfxBase = (struct GfxBase *) OpenLibrary("graphics.library", 0L);
  128.     if (!GfxBase)
  129.     {
  130.         printf("couldn't open graphics.library.\n");
  131.         exit (2);
  132.     }
  133.  
  134.     if (getargs( argv, myargs, NUMARGS( myargs ), NULL) < 0) goto DONE;
  135.  
  136.     view = GfxBase->ActiView;
  137.     vp = view->ViewPort;            /* ZZZ: more flexible next time?    */
  138.  
  139.     /* viewport intermediate copper lists */
  140.     if (intermed_bool)
  141.     {
  142.         dumpCopList( "DspIns", vp->DspIns );
  143.         dumpCopList( "SprIns", vp->SprIns );
  144.         dumpCopList( "ClrIns", vp->ClrIns );
  145.         dumpUCopList( vp->UCopIns );
  146.         default_work = 0;
  147.     }
  148.  
  149.     /* hardware headers    */
  150.     if (header_bool)
  151.     {
  152.         dumpcprheader( GfxBase->copinit );
  153.         default_work = 0;
  154.     }
  155.  
  156.     /* active hardware copper lists */
  157.     if (default_work || hardware_bool)
  158.     {
  159.         dumpcprlist( view->LOFCprList, all_bool);
  160.         dumpcprlist( view->SHFCprList, all_bool);
  161.     }
  162.  
  163. DONE:
  164.     if (GfxBase) CloseLibrary( GfxBase );
  165. }
  166.  
  167. /* display intermediate copper list    */
  168. dumpCopList( str, cl )
  169. char    *str;                /* name of this copper list    */
  170. struct CopList *cl;
  171. {
  172.     int count;
  173.     struct CopIns    *ci;
  174.  
  175.     printf("%s\n", str);
  176.  
  177.     while (cl)
  178.     {
  179.         ci = cl->CopIns;
  180.         for (count = cl->Count; count; --count)
  181.         {
  182.             if (dumpCopIns( ci++ )) break;    /* it sez: "next list"    */
  183.         }
  184.  
  185.         cl = cl->Next;
  186.     }
  187. }
  188.  
  189. /* dump Intermediate Copper List instruction
  190.  * return non-zero if it's time to branch to next list
  191.  */
  192. dumpCopIns( ci )
  193. struct CopIns *ci;
  194. {
  195.     UWORD    dest;
  196.  
  197.     switch (ci->OpCode)
  198.     {
  199.     case COPPER_MOVE:
  200.         dest = (ci->DESTADDR >> 1) &0xff;
  201.         printf("%lx\tCMOVE\t%04x,%s\n", ci, ci->DESTDATA, regname(dest));
  202.         break;
  203.     case COPPER_WAIT:
  204.         printf("%lx\tCWAIT\t%04x,%04x\n", ci, ci->HWAITPOS, ci->VWAITPOS);
  205.         break;
  206.     case CPRNXTBUF:
  207.         return (1);        /* is 'ci->nxtlist'    the same buffer as cl->Next? */
  208.         
  209.     default:
  210.         printf("unknown CopIns OpCodr: %x\n", ci->OpCode);
  211.     }
  212.     return (0);
  213. }
  214.  
  215. /* display User (intermediate) Copper List    */
  216. dumpUCopList( ucl )
  217. struct UCopList *ucl;
  218. {
  219.     while (ucl)
  220.     {
  221.         printf("UCopList block: %lx\n", ucl);
  222.         dumpCopList("...", ucl->FirstCopList);
  223.         ucl = ucl->Next;
  224.     }
  225. }
  226.  
  227. int skipped_color;
  228.  
  229. /*
  230.  * display hardware copper list
  231.  */
  232. dumpcprlist( coplist, all)
  233. struct cprlist *coplist;
  234. int                all;        /* 'all' means "color table loading, too?" */
  235. {
  236.     UWORD    *p;        /* clicks off amiga addresses    */
  237.     int        count;
  238.     UWORD    copinsbuff[2];
  239.  
  240.     if (!coplist) return;
  241.  
  242.     count = coplist->MaxCount;
  243.  
  244.     p = coplist->start;
  245.  
  246.     skipped_color = 0;        /* start him off on the right foot    */
  247.  
  248.     while (count--)
  249.     {
  250.         if (copDisasm( p, p[0], p[1], all)) break;
  251.         p += 2;
  252.     }
  253. }
  254.  
  255. /*
  256.  * display copinit copper list header
  257.  */
  258. dumpcprheader( p )
  259. UWORD    *p;        /* the actual instructions */
  260. {
  261.     while (! copDisasm(p, p[0], p[1], 1) )
  262.     {
  263.         p += 2;
  264.     }
  265. }
  266.  
  267. char    buff[256];
  268. char    linebuff[256];
  269.  
  270. /* formatted disassembly of hardware copper instruction
  271.  * return non-zero if you want to stop
  272.  */
  273. copDisasm( addr, op, w, all)
  274. APTR    addr;
  275. UWORD    op, w;
  276. {
  277.     UWORD vp, hp, vm, hm, da;
  278.     int    skcolor;
  279.     char    *name;
  280.  
  281.     int retval;
  282.  
  283.     skcolor = skipped_color;
  284.     skipped_color = 0;
  285.  
  286.     linebuff[0] = '\0';
  287.  
  288.     /* build output, defer display    */
  289.     sprintf(buff, "%08lx  %04x:%04x\t", addr, op, w);
  290.     strcat(linebuff,  buff);
  291.  
  292.     if (op & 1)        /* wait or skip    */
  293.     {
  294.         vp = (op >> 8) & 0xFF;
  295.         hp = (op >> 1) & 0x7F;
  296.         vm = (w >> 8) & 0x7F;
  297.         hm = (w >> 1) & 0x7F;
  298.  
  299.         sprintf(buff, "%s", w & 1 ? "SKIP" : "WAIT");
  300.         strcat(linebuff,  buff);
  301.  
  302.         if ((w & 0x8000) == 0) printf("BF");
  303.  
  304.         sprintf(buff, "\t(%02x,%02x)", hp, vp);
  305.         strcat(linebuff,  buff);
  306.  
  307.         if (hm != 0x7F || vm != 0x7F)
  308.         {
  309.             sprintf(buff, " mask (%02x,%02x)", hm, vm);
  310.             strcat(linebuff,  buff);
  311.         }
  312.  
  313.         /* comment    */
  314.         sprintf(buff, "\t\t; (x = %d, y = %d)", hp, vp);
  315.         strcat(linebuff,  buff);
  316.  
  317.         printf("%s\n", linebuff);    /* output    */
  318.  
  319.         retval = !(w & 1) && vp >= 0xFF && hp >= 0x7F;
  320.     }
  321.     else            /* move    */
  322.     {
  323.         retval = 0;
  324.         da = (op >> 1) & 0xFF;
  325.  
  326.         name = regname( da );
  327.  
  328.         sprintf(buff, "MOVE\t%04x,%s", w, name);
  329.         strcat(linebuff,  buff);
  330.  
  331.         prComment( name, w);    /* append comment to linebuff    */
  332.  
  333.         if (all || strncmp(name, "color", 5))
  334.         {
  335.             printf("%s\n", linebuff);
  336.         }
  337.         else
  338.         {
  339.             if (!skcolor)
  340.             {
  341.             printf("--- load color table ---\n");
  342.             }
  343.             skipped_color = 1;
  344.         }
  345.     }
  346.     return retval;
  347. }
  348.  
  349. /* give a little more info for the contents of some registers
  350.  * kind o' hokey method, eh?
  351.  */
  352. prComment( regname, w)
  353. char    *regname;
  354. {
  355.     int vp, hp;
  356.  
  357.     /* just in case */
  358.     vp = (w >> 8) & 0xFF;
  359.     hp = (w >> 0) & 0xFF;
  360.  
  361.     buff[0] = '\0';
  362.  
  363.     if (!strncmp(regname, "diwstrt", 7))
  364.     {
  365.         sprintf(buff, "\t; (left = %d, top = %d)", hp, vp);
  366.     }
  367.     else if (!strncmp(regname, "diwstop", 7))
  368.     {
  369.         sprintf(buff, "\t; (right = %d, bottom = %d)",
  370.             hp + 256, (!(vp & 0x80))?  vp+256 : vp);
  371.     }
  372.     else if (!strncmp(regname, "ddfstrt", 7))
  373.     {
  374.         sprintf(buff, "\t; pixel val = %d", w << 1);
  375.     }
  376.     else if (!strncmp(regname, "ddfstop", 7))
  377.     {
  378.         sprintf(buff, "\t; pixel val = %d", w << 1);
  379.     }
  380.  
  381.     strcat(linebuff, buff);
  382. }
  383.  
  384.