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