home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 6 / AACD06.ISO / AACD / Emulation / Atari800 / monitor.c < prev    next >
C/C++ Source or Header  |  1998-02-25  |  22KB  |  1,124 lines

  1. #include <stdio.h>
  2. #include <ctype.h>
  3. #include <unistd.h>
  4.  
  5. #ifdef VMS
  6. #include <unixio.h>
  7. #include <file.h>
  8. #else
  9. #include <fcntl.h>
  10. #endif
  11.  
  12. #include <stdlib.h>
  13.  
  14. static char *rcsid = "$Id: monitor.c,v 1.12 1996/10/09 22:02:07 david Exp $";
  15.  
  16. #include "atari.h"
  17. #include "cpu.h"
  18. #include "antic.h"
  19. #include "gtia.h"
  20. #include "pia.h"
  21. #include "pokey11.h"
  22. #include "mem.h"
  23.  
  24. #define FALSE   0
  25. #define TRUE    1
  26.  
  27. extern int count[256];
  28.  
  29. extern UBYTE    memory[65536];
  30.  
  31. extern UBYTE PORTA_mask,PORTB_mask;
  32.  
  33. extern int ypos;
  34.  
  35. #ifdef TRACE
  36. int tron = FALSE;
  37. #endif
  38.  
  39. unsigned int disassemble (UWORD addr1, UWORD addr2);
  40. void show_opcode (UBYTE instr);
  41. void show_operand (UBYTE instr);
  42.  
  43. char *get_token (char *string)
  44. {
  45.   static char     *s;
  46.   char            *t;
  47.  
  48.   if (string) s = string;                 /* New String */
  49.  
  50.   while (*s == ' ') s++;                  /* Skip Leading Spaces */
  51.  
  52.   if (*s)
  53.     {
  54.       t = s;                          /* Start of String */
  55.       while (*s != ' ' && *s)         /* Locate End of String */
  56.     {
  57.       s++;
  58.     }
  59.  
  60.       if (*s == ' ')                  /* Space Terminated ? */
  61.     {
  62.       *s = '\0';              /* C String Terminator */
  63.       s++;                    /* Point to Next Char */
  64.     }
  65.     }
  66.   else
  67.     {
  68.       t = NULL;
  69.     }
  70.   
  71.   return t;                               /* Pointer to String */
  72. }
  73.  
  74. void ReadDec(char *header,int *destination)
  75. {
  76. char buffer[256];
  77. int tmp;
  78. char *ep;
  79.  
  80.   printf("%s (%d) = ",header,*destination);
  81.   gets(buffer);
  82.   if (buffer[0]) {
  83.           tmp=strtol(buffer,&ep,0);
  84.       if (ep>buffer)
  85.         *destination=tmp;
  86.     }
  87.  
  88. }
  89.  
  90. int get_hex (char *string, UWORD *hexval)
  91. {
  92.   int    ihexval;
  93.   char    *t;
  94.  
  95.   t = get_token(string);
  96.   if (t)
  97.     {
  98.       if (!strcmp(t,"PC")) {
  99.     *hexval = regPC;
  100.     return 1;
  101.       }
  102.       if (!strcmp(t,"S")) {
  103.     *hexval = regS+0x100;
  104.     return 1;
  105.       }
  106.  
  107.       sscanf (t,"%x",&ihexval);
  108.       *hexval = ihexval;
  109.       return 1;
  110.     }
  111.  
  112.   return 0;
  113. }
  114.  
  115. int monitor (void)
  116. {
  117.   UWORD    addr;
  118.   UWORD    break_addr;
  119.   char    s[128];
  120.   int     p;
  121.  
  122.   addr = 0;
  123.  
  124.   CPU_GetStatus ();
  125.  
  126.   while (TRUE)
  127.     {
  128.       char    *t;
  129.  
  130.       printf ("> ");
  131.       fflush(stdout);
  132.       if (gets (s) == NULL)
  133.         {
  134.       printf("\n> CONT\n");
  135.       strcpy(s, "CONT");
  136.     }
  137.  
  138.       for (p=0;s[p]!=0;p++)
  139.     if (islower(s[p]))
  140.       s[p] = toupper(s[p]);
  141.  
  142.       t = get_token(s);
  143.       if (t == NULL)
  144.         {
  145.       continue;
  146.         }
  147.  
  148.       if (strcmp(t,"BREAK") == 0)
  149.     {
  150.       get_hex (NULL, &break_addr);
  151.     }
  152.       else if (strcmp(t,"CONT") == 0)
  153.     {
  154.       int i;
  155.  
  156.       for (i=0;i<256;i++)
  157.         count[i] = 0;
  158.  
  159.       return 1;
  160.     }
  161.       else if (strcmp(t,"DLIST") == 0)
  162.     {
  163.       UWORD dlist = DLISTINIT;
  164.       UWORD addr;
  165.       int done = FALSE;
  166.       int nlines = 0;
  167.  
  168.       while (!done)
  169.         {
  170.           UBYTE IR;
  171.  
  172.           printf ("%04x: ", dlist);
  173.  
  174.           IR = memory[dlist++];
  175.  
  176.           if (IR & 0x80)
  177.         printf ("DLI ");
  178.  
  179.           switch (IR & 0x0f)
  180.         {
  181.         case 0x00 :
  182.           printf ("%d BLANK", ((IR >> 4) & 0x07) + 1);
  183.           break;
  184.         case 0x01 :
  185.           addr = memory[dlist] | (memory[dlist+1] << 8);
  186.           if (IR & 0x40)
  187.             {
  188.               printf ("JVB %04x ", addr);
  189.               dlist += 2;
  190.               done = TRUE;
  191.             }
  192.           else
  193.             {
  194.               printf ("JMP %04x ", addr);
  195.               dlist = addr;
  196.             }
  197.           break;
  198.         default :
  199.           if (IR & 0x40)
  200.             {
  201.               addr = memory[dlist] | (memory[dlist+1] << 8);
  202.               dlist += 2;
  203.               printf ("LMS %04x ", addr);
  204.             }
  205.  
  206.           if (IR & 0x20)
  207.             printf ("VSCROL ");
  208.  
  209.           if (IR & 0x10)
  210.             printf ("HSCROL ");
  211.  
  212.           printf ("MODE %x ", IR & 0x0f);
  213.         }
  214.  
  215.           printf ("\n");
  216.           nlines++;
  217.  
  218.           if (nlines == 15)
  219.         {
  220.           char gash[4];
  221.  
  222.           printf ("Press return to continue: ");
  223.           gets (gash);
  224.           nlines = 0;
  225.         }
  226.         }
  227.     }
  228.       else if (strcmp(t,"SETPC") == 0)
  229.     {
  230.       get_hex (NULL, &addr);
  231.       
  232.       regPC = addr;
  233.     }
  234.       else if (strcmp(t,"SETS") == 0)
  235.     {
  236.       get_hex (NULL, &addr);
  237.       regS = addr & 0xff;
  238.     }
  239.       else if (strcmp(t,"SETA") == 0)
  240.     {
  241.       get_hex (NULL, &addr);
  242.       regA = addr & 0xff;
  243.     }
  244.       else if (strcmp(t,"SETX") == 0)
  245.     {
  246.       get_hex (NULL, &addr);
  247.       regX = addr & 0xff;
  248.     }
  249.       else if (strcmp(t,"SETY") == 0)
  250.     {
  251.       get_hex (NULL, &addr);
  252.       regY = addr & 0xff;
  253.     }
  254.       else if (strcmp(t,"SETN") == 0)
  255.     {
  256.       get_hex (NULL, &addr);
  257.       if (addr)
  258.         SetN;
  259.       else
  260.         ClrN;
  261.     }
  262.       else if (strcmp(t,"SETV") == 0)
  263.     {
  264.       get_hex (NULL, &addr);
  265.       if (addr)
  266.         SetV;
  267.       else
  268.         ClrV;
  269.     }
  270.       else if (strcmp(t,"SETB") == 0)
  271.     {
  272.       get_hex (NULL, &addr);
  273.       if (addr)
  274.         SetB;
  275.       else
  276.         ClrB;
  277.     }
  278.       else if (strcmp(t,"SETD") == 0)
  279.     {
  280.       get_hex (NULL, &addr);
  281.       if (addr)
  282.         SetD;
  283.       else
  284.         ClrD;
  285.     }
  286.       else if (strcmp(t,"SETI") == 0)
  287.     {
  288.       get_hex (NULL, &addr);
  289.       if (addr)
  290.         SetI;
  291.       else
  292.         ClrI;
  293.     }
  294.       else if (strcmp(t,"SETZ") == 0)
  295.     {
  296.       get_hex (NULL, &addr);
  297.       if (addr)
  298.         SetZ;
  299.       else
  300.         ClrZ;
  301.     }
  302.       else if (strcmp(t,"SETC") == 0)
  303.     {
  304.       get_hex (NULL, &addr);
  305.       if (addr)
  306.         SetC;
  307.       else
  308.         ClrC;
  309.     }
  310. #ifdef TRACE
  311.       else if (strcmp(t,"TRON") == 0)
  312.     tron = TRUE;
  313.       else if (strcmp(t,"TROFF") == 0)
  314.     tron = FALSE;
  315. #endif
  316.       else if (strcmp(t,"PROFILE") == 0)
  317.     {
  318.       int i;
  319.  
  320.       for (i=0;i<10;i++)
  321.         {
  322.           int max, instr;
  323.           int j;
  324.  
  325.           max = count[0];
  326.           instr = 0;
  327.  
  328.           for (j=1;j<256;j++)
  329.         {
  330.           if (count[j] > max)
  331.             {
  332.               max = count[j];
  333.               instr = j;
  334.             }
  335.         }
  336.  
  337.           if (max > 0)
  338.         {
  339.           count[instr] = 0;
  340.           printf ("%02x has been executed %d times\n",
  341.               instr, max);
  342.         }
  343.           else
  344.         {
  345.           printf ("Instruction Profile data not available\n");
  346.           break;
  347.         }
  348.         }
  349.     }
  350.       else if (strcmp(t,"SHOW") == 0)
  351.     {
  352.       printf ("PC=%04x, A=%02x, S=%02x, X=%02x, Y=%02x, P=%02x\n",
  353.           regPC,
  354.           regA,
  355.           regS,
  356.           regX,
  357.           regY,
  358.           regP);
  359.     }
  360.       else if (strcmp(t,"ROM") == 0)
  361.     {
  362.       UWORD    addr1;
  363.       UWORD    addr2;
  364.       
  365.       int    status;
  366.  
  367.       status = get_hex (NULL, &addr1);
  368.       status |= get_hex (NULL, &addr2);
  369.       
  370.       if (status)
  371.         {
  372.           SetROM (addr1, addr2);
  373.           printf ("Changed Memory from %4x to %4x into ROM\n",
  374.               addr1, addr2);
  375.         }
  376.       else
  377.         {
  378.           printf ("*** Memory Unchanged (Missing Parameter) ***\n");
  379.         }
  380.     }
  381.       else if (strcmp(t,"RAM") == 0)
  382.     {
  383.       UWORD    addr1;
  384.       UWORD    addr2;
  385.  
  386.       int    status;
  387.  
  388.       status = get_hex (NULL, &addr1);
  389.       status |= get_hex (NULL, &addr2);
  390.  
  391.       if (status)
  392.         {
  393.           SetRAM (addr1, addr2);
  394.           printf ("Changed Memory from %4x to %4x into RAM\n",
  395.               addr1, addr2);
  396.         }
  397.       else
  398.         {
  399.           printf ("*** Memory Unchanged (Missing Parameter) ***\n");
  400.         }
  401.     }
  402.       else if (strcmp(t,"WRITE") == 0)
  403.     {
  404.       UWORD    addr1;
  405.       UWORD    addr2;
  406.  
  407.       int    status;
  408.       
  409.       status = get_hex (NULL, &addr1);
  410.       status |= get_hex (NULL, &addr2);
  411.  
  412.       if (status)
  413.         {
  414.           int    fd;
  415.           
  416.           fd = open ("memdump.dat", O_CREAT | O_TRUNC | O_WRONLY, 0777);
  417.           if (fd == -1)
  418.         {
  419.           perror ("open");
  420.           return 0;
  421.         }
  422.  
  423.           write (fd, &memory[addr1], addr2 - addr1 + 1);
  424.           
  425.           close (fd);
  426.         }
  427.     }
  428.       else if (strcmp(t,"SUM") == 0)
  429.     {
  430.       UWORD    addr1;
  431.       UWORD    addr2;
  432.       int status;
  433.  
  434.       status = get_hex (NULL, &addr1);
  435.       status |= get_hex (NULL, &addr2);
  436.       
  437.       if (status)
  438.         {
  439.           int sum = 0;
  440.           int i;
  441.  
  442.           for (i=addr1;i<=addr2;i++)
  443.         sum += (UWORD)memory[i];
  444.           printf ("SUM: %x\n", sum);
  445.         }
  446.     }
  447.       else if (strcmp(t,"D") == 0)
  448.     {
  449.       int    addr1;
  450.       int    addr2;
  451.       UWORD    xaddr1;
  452.       UWORD    xaddr2;
  453.       UWORD    temp;
  454.       int    i;
  455.  
  456.       xaddr1 = addr;
  457.       xaddr2 = 0;
  458.  
  459.       get_hex (NULL, &xaddr1);
  460.       get_hex (NULL, &xaddr2);
  461.       
  462.       addr1 = xaddr1;
  463.       addr2 = xaddr2;
  464.  
  465.       if (addr2 == 0) addr2 = addr1 + 255;
  466.       
  467.       addr = addr2 + 1;
  468.       
  469.       while (addr1 <= addr2)
  470.         {
  471.           temp = addr1;
  472.           
  473.           printf ("%4x : ",temp);
  474.           
  475.           for (i=0;i<16;i++)
  476.         {
  477.           printf ("%2x ",memory[temp]);
  478.           temp++;
  479.           if (temp > addr2) break;
  480.         }
  481.  
  482.           temp = addr1;
  483.  
  484.           printf ("\t");
  485.  
  486.           for (i=0;i<16;i++)
  487.         {
  488.           if (isalnum(memory[temp]))
  489.             {
  490.               printf ("%c",memory[temp]);
  491.             }
  492.           else
  493.             {
  494.               printf (".");
  495.             }
  496.           temp++;
  497.           if (temp > addr2) break;
  498.         }
  499.  
  500.           printf ("\n");
  501.  
  502.           addr1 += 16;
  503.         }
  504.     }
  505.       else if (strcmp(t,"M") == 0)
  506.     {
  507.       UWORD    addr;
  508.       UWORD    temp;
  509.  
  510.       get_hex (NULL, &addr);
  511.       
  512.       while (get_hex(NULL, &temp))
  513.         {
  514.           memory[addr] = (UBYTE)temp;
  515.           addr++;
  516.         }
  517.     }
  518.       else if (strcmp(t,"Y") == 0)
  519.     {
  520.       UWORD    addr1;
  521.       UWORD    addr2;
  522.  
  523.       addr1 = addr;
  524.       addr2 = 0;
  525.  
  526.       get_hex (NULL, &addr1);
  527.       get_hex (NULL, &addr2);
  528.  
  529.       addr = disassemble (addr1,addr2);
  530.     }
  531.       else if (strcmp(t,"ANTIC") == 0)
  532.     {
  533.       printf ("DMACTL=%02x    CHACTL=%02x    DLIST=%04x   "
  534.           "HSCROL=%02x    VSCROL=%02x\n",
  535.           DMACTL, CHACTL, DLIST , HSCROL, VSCROL);
  536.       printf ("PMBASE=%02x    CHBASE=%02x    WSYNC= xx    "
  537.           "VCOUNT=%02x    PENH=  xx    PENV=  xx\n",
  538.           PMBASE, CHBASE, ypos >> 1);
  539.       printf ("NMIEN= %02x    NMIRES=xx\n", NMIEN);
  540.       printf ("YPos = %04x\n",ypos);
  541.     }
  542.       else if (strcmp(t,"POKEY") == 0)
  543.     {
  544.       printf ("IRQEN=%02x     IRQST=%02x     KBCODE=%02x   "
  545.           "SKSTAT=%02x    AUDCTL=%02x\n",
  546.           IRQEN,IRQST,KBCODE,SKSTAT,AUDCTL);
  547.       printf ("AUDF1=%02x     AUDC1=%02x     AUDcnt1=%08lx  "
  548.           "AUDmax1=%08lx\n",
  549.           AUDF[0],AUDC[0],Div_n_irq[0],Div_n_max[0]);
  550.       printf ("AUDF2=%02x     AUDC2=%02x     AUDcnt2=%08lx  "
  551.           "AUDmax2=%08lx\n",
  552.           AUDF[1],AUDC[1],Div_n_irq[1],Div_n_max[1]);
  553.       printf ("AUDF3=%02x     AUDC3=%02x     AUDcnt3=%08lx  "
  554.           "AUDmax3=%08lx\n",
  555.           AUDF[2],AUDC[2],Div_n_irq[2],Div_n_max[2]);
  556.       printf ("AUDF4=%02x     AUDC4=%02x     AUDcnt4=%08lx  "
  557.           "AUDmax4=%08lx\n",
  558.           AUDF[3],AUDC[3],Div_n_irq[3],Div_n_max[3]);
  559.     }
  560.       else if (strcmp(t,"PIA") == 0)
  561.     {
  562.       printf("PORTA=%02x      PORTB=%02x\n",
  563.          PORTA,PORTB);
  564.       printf("PACTL=%02x      PBCTL=%02x\n",
  565.          PACTL,PBCTL);
  566.       printf("PAmsk=%02x      PBmsk=%02x\n",
  567.          PORTA_mask,PORTB_mask);
  568.     }
  569.       else if (strcmp(t,"GTIA") == 0)
  570.     {
  571.       printf ("HPOSP0=%02x    HPOSP1=%02x    HPOSP2=%02x    "
  572.           "HPOSP3=%02x    HPOSM0=%02x    HPOSM1=%02x\n",
  573.           HPOSP0, HPOSP1, HPOSP2, HPOSP3, HPOSM0, HPOSM1);
  574.       printf ("HPOSM2=%02x    HPOSM3=%02x    SIZEP0=%02x    "
  575.           "SIZEP1=%02x    SIZEP2=%02x    SIZEP3=%02x\n",
  576.           HPOSM2, HPOSM3, SIZEP0, SIZEP1, SIZEP2, SIZEP3);
  577.       printf ("SIZEM= %02x    GRAFP0=%02x    GRAFP1=%02x    "
  578.           "GRAFP2=%02x    GRAFP3=%02x    GRAFM =%02x\n",
  579.           SIZEM, GRAFP0, GRAFP1, GRAFP2, GRAFP3, GRAFM);
  580.       printf ("COLPM0=%02x    COLPM1=%02x    COLPM2=%02x    "
  581.           "COLPM3=%02x    COLPF0=%02x    COLPF1=%02x\n",
  582.           COLPM0, COLPM1, COLPM2, COLPM3, COLPF0, COLPF1);
  583.       printf ("COLPF2=%02x    COLPF3=%02x    COLBK= %02x    "
  584.           "PRIOR= %02x    GRACTL=%02x\n",
  585.           COLPF2, COLPF3, COLBK, PRIOR, GRACTL);
  586.       /* printf ("TRIG0= %02x    TRIG1= %02x    TRIG2= %02x    "
  587.           "TRIG3= %02x\n",
  588.           Atari_TRIG(0),Atari_TRIG(1),Atari_TRIG(2),Atari_TRIG(3)); */
  589.     }
  590.       else if (strcmp(t,"TIMING") == 0) 
  591.     {
  592.       ReadDec("Middle horizontal cycle",&cc_middle);
  593.       ReadDec("DLI reaction delay",&dli_delay);
  594.       ReadDec("Cycles after WSYNC",&after_wsync);
  595.       ReadDec("Cycles before DMA",&before_dma);
  596.       ReadDec("WSYNC bonus cycles",&wsync_bonus);
  597.       ReadDec("VSYNC line",&vsync_pos);
  598.     }
  599.       else if (strcmp(t,"HELP") == 0 || strcmp(t,"?") == 0)
  600.     {
  601.       printf ("SET{PC,A,S,X,Y} hexval    - Set Register Value\n"
  602.           "SET{N,V,B,D,I,Z,C} hexval - Set Flag Value\n"
  603.           "D [startaddr] [endaddr]   - Display Memory\n"
  604.           "M [startaddr] [hexval...] - Modify Memory\n"
  605.           "Y [startaddr] [endaddr]   - Disassemble Memory\n"
  606.           "ROM addr1 addr2           - Convert Memory Block into ROM\n"
  607.           "RAM addr1 addr2           - Convert Memory Block into RAM\n"
  608.           "CONT                      - Continue\n"
  609.           "SHOW                      - Show Registers\n"
  610.           "WRITE startaddr endaddr   - Write specified area of memory to memdump.dat\n"
  611.           "SUM [startaddr] [endaddr] - SUM of specified memory range\n"
  612. #ifdef TRACE
  613.           "TRON                      - Trace On\n"
  614.           "TROFF                     - Trace Off\n"
  615. #endif
  616.           "ANTIC                     - Display ANTIC registers\n"
  617.           "GTIA                      - Display GTIA registers\n"
  618.           "PIA                       - Display PIA registers\n"
  619.           "POKEY                     - Display POKEY registers\n"
  620.           "DLIST                     - Display current display list\n"
  621.           "PROFILE                   - Display profiling statistics\n"
  622.           "TIMING                    - Setup horizontal timing\n"
  623.           "QUIT                      - Quit Emulation\n"
  624.           "HELP or ?                 - This Text\n");
  625.     }
  626.       else if (strcmp(t,"QUIT") == 0)
  627.     {
  628.       return 0;
  629.     }
  630.       else
  631.     {
  632.       printf ("Invalid command.\n");
  633.     }
  634.     }
  635. }
  636.  
  637. static UWORD    addr;
  638.  
  639. unsigned int disassemble (UWORD addr1, UWORD addr2)
  640. {
  641.     UBYTE    instr;
  642.     int    count;
  643.  
  644.     addr = addr1;
  645.  
  646.     count = (addr2 == 0) ? 20 : 0;
  647.  
  648.     while (addr < addr2 || count > 0)
  649.     {
  650.         printf ("%x\t",addr);
  651.  
  652.         instr = memory[addr];
  653.         addr++;
  654.  
  655.         show_opcode (instr);
  656.         show_operand (instr);
  657.  
  658.         printf ("\n");
  659.         
  660.         if (count > 0) count--;
  661.     }
  662.  
  663.     return addr;
  664. }
  665.  
  666. void show_opcode (UBYTE instr)
  667. {
  668.     switch (instr)
  669.     {
  670.     case 0x6d : case 0x65 : case 0x69:
  671.     case 0x79 : case 0x7d : case 0x61 :
  672.     case 0x71 : case 0x75 :
  673.       printf ("ADC");
  674.       break;
  675.     case 0x2d : case 0x25 : case 0x29 :
  676.     case 0x39 : case 0x3d : case 0x21 :
  677.     case 0x31 : case 0x35 :
  678.       printf ("AND");
  679.       break;
  680.     case 0x0e : case 0x06 : case 0x1e :
  681.     case 0x16 :
  682.       printf ("ASL");
  683.       break;
  684.     case 0x0a :
  685.       printf ("ASL\tA");
  686.       break;
  687.     case 0x90 :
  688.       printf ("BCC");
  689.       break;
  690.     case 0xb0 :
  691.       printf ("BCS");
  692.       break;
  693.     case 0xf0 :
  694.       printf ("BEQ");
  695.       break;
  696.     case 0x2c : case 0x24 :
  697.       printf ("BIT");
  698.       break;
  699.     case 0x30 :
  700.       printf ("BMI");
  701.       break;
  702.     case 0xd0 :
  703.       printf ("BNE");
  704.       break;
  705.     case 0x10 :
  706.       printf ("BPL");
  707.       break;
  708.     case 0x00 :
  709.       printf ("BRK");
  710.       break;
  711.     case 0x50 :
  712.       printf ("BVC");
  713.       break;
  714.     case 0x70 :
  715.       printf ("BVS");
  716.       break;
  717.     case 0x18 :
  718.       printf ("CLC");
  719.       break;
  720.     case 0xd8 :
  721.       printf ("CLD");
  722.       break;
  723.     case 0x58 :
  724.       printf ("CLI");
  725.       break;
  726.     case 0xb8 :
  727.       printf ("CLV");
  728.       break;
  729.     case 0xcd : case 0xc5 : case 0xc9 :
  730.     case 0xdd : case 0xd9 :    case 0xc1 :
  731.     case 0xd1 : case 0xd5 :
  732.       printf ("CMP");
  733.       break;
  734.     case 0xec : case 0xe4 : case 0xe0 :
  735.       printf ("CPX");
  736.       break;
  737.     case 0xcc : case 0xc4 : case 0xc0 :
  738.       printf ("CPY");
  739.       break;
  740.     case 0xce : case 0xc6 : case 0xde :
  741.     case 0xd6 :
  742.       printf ("DEC");
  743.       break;
  744.     case 0xca :
  745.       printf ("DEX");
  746.       break;
  747.     case 0x88 :
  748.       printf ("DEY");
  749.       break;
  750.     case 0x4d : case 0x45 : case 0x49 :
  751.     case 0x5d : case 0x59 : case 0x41 :
  752.     case 0x51 : case 0x55 :
  753.       printf ("EOR");
  754.       break;
  755.     case 0xff : /* [unofficial] */
  756.       printf ("ESC");
  757.       break;
  758.     case 0xee : case 0xe6 : case 0xfe :
  759.     case 0xf6 :
  760.       printf ("INC");
  761.       break;
  762.     case 0xe8 :
  763.       printf ("INX");
  764.       break;
  765.     case 0xc8 :
  766.       printf ("INY");
  767.       break;
  768.     case 0x4c : case 0x6c :
  769.       printf ("JMP");
  770.       break;
  771.     case 0x20 :
  772.       printf ("JSR");
  773.       break;
  774.     case 0xa3 : case 0xa7 : case 0xaf : /* [unofficial] */
  775.     case 0xb3 : case 0xb7 : case 0xbf :
  776.       printf ("LAX");
  777.       break;
  778.     case 0xad : case 0xa5 : case 0xa9 :
  779.     case 0xbd : case 0xb9 : case 0xa1 :
  780.     case 0xb1 : case 0xb5 :
  781.       printf ("LDA");
  782.       break;
  783.     case 0xae : case 0xa6 : case 0xa2 :
  784.     case 0xbe : case 0xb6 :
  785.       printf ("LDX");
  786.       break;
  787.     case 0xac : case 0xa4 : case 0xa0 :
  788.     case 0xbc : case 0xb4 :
  789.       printf ("LDY");
  790.       break;
  791.     case 0x4e : case 0x46 : case 0x5e :
  792.     case 0x56 :
  793.       printf ("LSR");
  794.       break;
  795.     case 0x4a :
  796.       printf ("LSR\tA");
  797.       break;
  798.     case 0xea :
  799.       printf ("NOP");
  800.       break;
  801.     case 0x0d : case 0x05 :    case 0x09 :
  802.     case 0x1d : case 0x19 :    case 0x01 :
  803.     case 0x11 : case 0x15 :
  804.       printf ("ORA");
  805.       break;
  806.     case 0x48 :
  807.       printf ("PHA");
  808.       break;
  809.     case 0x08 :
  810.       printf ("PHP");
  811.       break;
  812.     case 0x68 :
  813.       printf ("PLA");
  814.       break;
  815.     case 0x28 :
  816.       printf ("PLP");
  817.       break;
  818.     case 0x2e : case 0x26 : case 0x3e :
  819.     case 0x36 :
  820.       printf ("ROL");
  821.       break;
  822.     case 0x2a :
  823.       printf ("ROL\tA");
  824.       break;
  825.     case 0x6e : case 0x66 : case 0x7e :
  826.     case 0x76 :
  827.       printf ("ROR");
  828.       break;
  829.     case 0x6a :
  830.       printf ("ROR\tA");
  831.       break;
  832.     case 0x40 :
  833.       printf ("RTI");
  834.       break;
  835.     case 0x60 :
  836.       printf ("RTS");
  837.       break;
  838.     case 0xed : case 0xe5 : case 0xe9 :
  839.     case 0xfd : case 0xf9 :    case 0xe1 :
  840.     case 0xf1 : case 0xf5 :
  841.       printf ("SBC");
  842.       break;
  843.     case 0x38 :
  844.       printf ("SEC");
  845.       break;
  846.     case 0xf8 :
  847.       printf ("SED");
  848.       break;
  849.     case 0x78 :
  850.       printf ("SEI");
  851.       break;
  852.     case 0x8d : case 0x85 :    case 0x9d :
  853.     case 0x99 : case 0x81 :    case 0x91 :
  854.     case 0x95 :
  855.       printf ("STA");
  856.       break;
  857.     case 0x8e : case 0x86 : case 0x96 :
  858.       printf ("STX");
  859.       break;
  860.     case 0x8c : case 0x84 : case 0x94 :
  861.       printf ("STY");
  862.       break;
  863.     case 0xaa :
  864.       printf ("TAX");
  865.       break;
  866.     case 0xa8 :
  867.       printf ("TAY");
  868.       break;
  869.     case 0xba :
  870.       printf ("TSX");
  871.       break;
  872.     case 0x8a :
  873.       printf ("TXA");
  874.       break;
  875.     case 0x9a :
  876.       printf ("TXS");
  877.       break;
  878.     case 0x98 :
  879.       printf ("TYA");
  880.       break;
  881.     default :
  882.       printf ("*** ILLEGAL INSTRUCTION (%x) ***",instr);
  883.       break;
  884.     }
  885. }
  886.  
  887. void show_operand (UBYTE instr)
  888. {
  889.     UBYTE    byte;
  890.     UWORD    word;
  891.  
  892.     switch (instr)
  893.     {
  894. /*
  895.     =========================
  896.     Absolute Addressing Modes
  897.     =========================
  898. */
  899.         case 0x6d :    /* ADC */
  900.         case 0x2d :    /* AND */
  901.         case 0x0e :    /* ASL */
  902.         case 0x2c :    /* BIT */
  903.         case 0xcd :    /* CMP */
  904.         case 0xec :    /* CPX */
  905.         case 0xcc :    /* CPY */
  906.         case 0xce :    /* DEC */
  907.         case 0x4d :    /* EOR */
  908.         case 0xee :    /* INC */
  909.         case 0x4c :    /* JMP */
  910.         case 0x20 :    /* JSR */
  911.         case 0xaf :     /* LAX [unofficial] */
  912.         case 0xad :    /* LDA */
  913.         case 0xae :    /* LDX */
  914.         case 0xac :    /* LDY */
  915.         case 0x4e :    /* LSR */
  916.         case 0x0d :    /* ORA */
  917.         case 0x2e :    /* ROL */
  918.         case 0x6e :    /* ROR */
  919.         case 0xed :    /* SBC */
  920.         case 0x8d :    /* STA */
  921.         case 0x8e :    /* STX */
  922.         case 0x8c :    /* STY */
  923.             word = (memory[addr+1] << 8) | memory[addr];
  924.             printf ("\t$%x",word);
  925.             addr += 2;
  926.             break;
  927. /*
  928.     ======================
  929.     0-Page Addressing Mode
  930.     ======================
  931. */
  932.         case 0x65 :    /* ADC */
  933.         case 0x25 :    /* AND */
  934.         case 0x06 :    /* ASL */
  935.         case 0x24 :    /* BIT */
  936.         case 0xc5 :    /* CMP */
  937.         case 0xe4 :    /* CPX */
  938.         case 0xc4 :    /* CPY */
  939.         case 0xc6 :    /* DEC */
  940.         case 0x45 :    /* EOR */
  941.         case 0xe6 :    /* INC */
  942.         case 0xa7 :     /* LAX [unofficial] */
  943.         case 0xa5 :    /* LDA */
  944.         case 0xa6 :    /* LDX */
  945.         case 0xa4 :    /* LDY */
  946.         case 0x46 :    /* LSR */
  947.         case 0x05 :    /* ORA */
  948.         case 0x26 :    /* ROL */
  949.         case 0x66 :    /* ROR */
  950.         case 0xe5 :    /* SBC */
  951.         case 0x85 :    /* STA */
  952.         case 0x86 :    /* STX */
  953.         case 0x84 :    /* STY */
  954.             byte = memory[addr];
  955.             addr++;
  956.             printf ("\t$%x",byte);
  957.             break;
  958. /*
  959.     ========================
  960.     Relative Addressing Mode
  961.     ========================
  962. */
  963.         case 0x90 :    /* BCC */
  964.         case 0xb0 :    /* BCS */
  965.         case 0xf0 :    /* BEQ */
  966.         case 0x30 :    /* BMI */
  967.         case 0xd0 :    /* BNE */
  968.         case 0x10 :    /* BPL */
  969.         case 0x50 :    /* BVC */
  970.         case 0x70 :    /* BVS */
  971.             byte = memory[addr];
  972.             addr++;
  973.             printf ("\t$%x",addr+(SBYTE)byte);
  974.             break;
  975. /*
  976.     =========================
  977.     Immediate Addressing Mode
  978.     =========================
  979. */
  980.         case 0x69 :    /* ADC */
  981.         case 0x29 :    /* AND */
  982.         case 0xc9 :    /* CMP */
  983.         case 0xe0 :    /* CPX */
  984.         case 0xc0 :    /* CPY */
  985.         case 0x49 :    /* EOR */
  986.         case 0xa9 :    /* LDA */
  987.         case 0xa2 :    /* LDX */
  988.         case 0xa0 :    /* LDY */
  989.         case 0x09 :    /* ORA */
  990.         case 0xe9 :    /* SBC */
  991.         case 0xff :    /* ESC */
  992.             byte = memory[addr];
  993.             addr++;
  994.             printf ("\t#$%x",byte);
  995.             break;
  996. /*
  997.     =====================
  998.     ABS,X Addressing Mode
  999.     =====================
  1000. */
  1001.         case 0x7d :    /* ADC */
  1002.         case 0x3d :    /* AND */
  1003.         case 0x1e :    /* ASL */
  1004.         case 0xdd :    /* CMP */
  1005.         case 0xde :    /* DEC */
  1006.         case 0x5d :    /* EOR */
  1007.         case 0xfe :    /* INC */
  1008.         case 0xbd :    /* LDA */
  1009.         case 0xbc :    /* LDY */
  1010.         case 0x5e :    /* LSR */
  1011.         case 0x1d :    /* ORA */
  1012.         case 0x3e :    /* ROL */
  1013.         case 0x7e :    /* ROR */
  1014.         case 0xfd :    /* SBC */
  1015.         case 0x9d :    /* STA */
  1016.             word = (memory[addr+1] << 8) | memory[addr];
  1017.             printf ("\t$%x,X",word);
  1018.             addr += 2;
  1019.             break;
  1020. /*
  1021.     =====================
  1022.     ABS,Y Addressing Mode
  1023.     =====================
  1024. */
  1025.         case 0x79 :    /* ADC */
  1026.         case 0x39 :    /* AND */
  1027.         case 0xd9 :    /* CMP */
  1028.         case 0x59 :    /* EOR */
  1029.         case 0xbf :     /* LAX [unofficial] */
  1030.         case 0xb9 :    /* LDA */
  1031.         case 0xbe :    /* LDX */
  1032.         case 0x19 :    /* ORA */
  1033.         case 0xf9 :    /* SBC */
  1034.         case 0x99 :    /* STA */
  1035.             word = (memory[addr+1] << 8) | memory[addr];
  1036.             printf ("\t$%x,Y",word);
  1037.             addr += 2;
  1038.             break;
  1039. /*
  1040.     =======================
  1041.     (IND,X) Addressing Mode
  1042.     =======================
  1043. */
  1044.         case 0x61 :    /* ADC */
  1045.         case 0x21 :    /* AND */
  1046.         case 0xc1 :    /* CMP */
  1047.         case 0x41 :    /* EOR */
  1048.         case 0xa3 :     /* LAX [unofficial] */
  1049.         case 0xa1 :    /* LDA */
  1050.         case 0x01 :    /* ORA */
  1051.         case 0xe1 :    /* SBC */
  1052.         case 0x81 :    /* STA */
  1053.             byte = memory[addr];
  1054.             addr++;
  1055.             printf ("\t($%x,X)",byte);
  1056.             break;
  1057. /*
  1058.     =======================
  1059.     (IND),Y Addressing Mode
  1060.     =======================
  1061. */
  1062.         case 0x71 :    /* ADC */
  1063.         case 0x31 :    /* AND */
  1064.         case 0xd1 :    /* CMP */
  1065.         case 0x51 :    /* EOR */
  1066.         case 0xb3 :     /* LAX [unofficial] */
  1067.         case 0xb1 :    /* LDA */
  1068.         case 0x11 :    /* ORA */
  1069.         case 0xf1 :    /* SBC */
  1070.         case 0x91 :    /* STA */
  1071.             byte = memory[addr];
  1072.             addr++;
  1073.             printf ("\t($%x),Y",byte);
  1074.             break;
  1075. /*
  1076.     ========================
  1077.     0-Page,X Addressing Mode
  1078.     ========================
  1079. */
  1080.         case 0x75 :    /* ADC */
  1081.         case 0x35 :    /* AND */
  1082.         case 0x16 :    /* ASL */
  1083.         case 0xd5 :    /* CMP */
  1084.         case 0xd6 :    /* DEC */
  1085.         case 0x55 :    /* EOR */
  1086.         case 0xf6 :    /* INC */
  1087.         case 0xb5 :    /* LDA */
  1088.         case 0xb4 :    /* LDY */
  1089.         case 0x56 :    /* LSR */
  1090.         case 0x15 :    /* ORA */
  1091.         case 0x36 :    /* ROL */
  1092.         case 0x76 :    /* ROR */
  1093.         case 0xf5 :    /* SBC */
  1094.         case 0x95 :    /* STA */
  1095.         case 0x94 :    /* STY */
  1096.             byte = memory[addr];
  1097.             addr++;
  1098.             printf ("\t$%x,X",byte);
  1099.             break;
  1100. /*
  1101.     ========================
  1102.     0-Page,Y Addressing Mode
  1103.     ========================
  1104. */
  1105.         case 0xb7 :     /* LAX [unofficial] */
  1106.         case 0xb6 :    /* LDX */
  1107.         case 0x96 :    /* STX */
  1108.             byte = memory[addr];
  1109.             addr++;
  1110.             printf ("\t$%x,Y",byte);
  1111.             break;
  1112. /*
  1113.     ========================
  1114.     Indirect Addressing Mode
  1115.     ========================
  1116. */
  1117.         case 0x6c :    /* printf ("JMP INDIRECT at %x\n",instr_addr); */
  1118.             word = (memory[addr+1] << 8) | memory[addr];
  1119.             printf ("\t($%x)",word);
  1120.             addr += 2;
  1121.             break;
  1122.     }
  1123. }
  1124.