home *** CD-ROM | disk | FTP | other *** search
/ ST-Computer Leser 2002 January / STC_CD_01_2002.iso / JAGUAR / JAG_SRC / SOURCE / DISARISC.C < prev    next >
C/C++ Source or Header  |  2001-08-11  |  12KB  |  443 lines

  1. ////////////////////////////////////////////////////////////////////////////////
  2. // Jagulator: Atari Jaguar Console Emulation Project (disarisc.c)
  3. // -----------------------------------------------------------------------------
  4. // Jagulator is the Copyright (c) RealityMan 1998-2001 and is provided "as is" 
  5. // without any expressed or implied warranty. I have no Trademarks, Legal or 
  6. // otherwise. Atari, Jaguar and the Atari Logo are copyright Hasbro Inc. All 
  7. // other Copyrights and Trademarks are acknowledged. This project is in no way 
  8. // linked to Atari/Hasbro or other associated Atari companies.                
  9. //
  10. // 07-07-2001 GH: New Source, Rewritten for Release 1.5.0
  11. // 00-00-0000 GH: All Previous Source Considered as Development Code Only
  12.  
  13. #include "core.h"
  14.  
  15. ////////////////////////////////////////////////////////////////////////////////
  16. // Globals
  17.  
  18.    char    gpu_instr[][64] = {
  19.        "add     ", "addc    ", "addq    ", "addqt   ",
  20.       "sub     ", "subc    ", "subq    ", "subqt   ",
  21.        "neg     ", "and     ", "or      ", "xor     ",
  22.       "not     ", "btst    ", "bset    ", "bclr    ",
  23.        "mult    ", "imult   ", "imultn  ", "resmac  ",
  24.       "imacn   ", "div     ", "abs     ", "sh      ",
  25.        "shlq    ", "shrq    ", "sha     ", "sharq   ",
  26.       "ror     ", "rorq    ", "cmp     ", "cmpq    ",
  27.        "sat8    ", "sat16   ", "move    ", "moveq   ",
  28.       "moveta  ", "movefa  ", "movei   ", "loadb   ",
  29.        "loadw   ", "load    ", "loadp   ", "load    ",
  30.       "load    ", "storeb  ", "storew  ", "store   ",
  31.        "storep  ", "store   ", "store   ", "move    ",
  32.       "jump    ", "jr      ", "mmult   ", "mtoi    ",
  33.        "normi   ", "nop     ", "load    ", "load    ",
  34.       "store   ", "store   ", "sat24   ", ""
  35.     };
  36.  
  37.    char    dsp_instr[][64] = {
  38.        "add     ", "addc    ", "addq    ", "addqt   ",
  39.       "sub     ", "subc    ", "subq    ", "subqt   ",
  40.        "neg     ", "and     ", "or      ", "xor     ",
  41.       "not     ", "btst    ", "bset    ", "bclr    ",
  42.       "mult    ", "imult   ", "imultn  ", "resmac  ",
  43.       "imacn   ", "div     ", "abs     ", "sh      ",
  44.        "shlq    ", "shrq    ", "sha     ", "sharq   ",
  45.       "ror     ", "rorq    ", "cmp     ", "cmpq    ",
  46.        "subqmod ", "sat16s  ", "move    ", "moveq   ",
  47.       "moveta  ", "movefa  ", "movei   ", "loadb   ",
  48.        "loadw   ", "load    ", "sat32s  ", "load    ",
  49.       "load    ", "storeb  ", "storew  ", "store   ",
  50.        "mirror  ", "store   ", "store   ", "move    ",
  51.       "jump    ", "jr      ", "mmult   ", "mtoi    ",
  52.        "normi   ", "nop     ", "load    ", "load    ",
  53.       "store   ", "store   ", "illegal ", "addqmod "
  54.     };
  55.  
  56.    dword debuggpc;                     // Debug GPU Program Counter
  57.    dword debugdpc;                     // Debug DSP Program Counter
  58.  
  59. ////////////////////////////////////////////////////////////////////////////////
  60. // 
  61.  
  62. char    *decode_flags(int flags)    /* Return a text string for the flags
  63.                         field in a conditional instruction */
  64. {
  65.     static char    flastr[8+1];    /* Must be static so exists after return */
  66.  
  67.     *flastr='\0';        /* Clear the result string */
  68.  
  69.     if (flags==0x05) return("HI");    /* Special case for Carry clear and Zero clear */
  70.     if (flags&(1<<0))    strcat(flastr,"NE");    /* Zero clear */
  71.     if (flags&(1<<1))    strcat(flastr,"EQ");    /* Zero set */
  72.     if (flags&(1<<4)) {    /* If set then bits 2,3 are for -ve flag */
  73.         if (flags&(1<<2))    strcat(flastr,"PL");    /* Sign clear */
  74.         if (flags&(1<<3))    strcat(flastr,"MI");    /* Sign set */
  75.     } else {
  76.         if (flags&(1<<2))    strcat(flastr,"CC");    /* Carry clear */
  77.         if (flags&(1<<3))    strcat(flastr,"CS");    /* Carry set */
  78.     }
  79.     return(flastr);
  80. }
  81.  
  82. ////////////////////////////////////////////////////////////////////////////////
  83. // Disassemble DSP Code
  84.  
  85.    void dspdebug_disassemble( int n ) 
  86.    {
  87.       #ifdef DEBUG
  88.       dword iw, src, dst, ir;
  89.        long    msw, lsw;
  90.        long    movei_long;
  91.  
  92.        while( n-- ) 
  93.       {
  94.          iw = mem_readword( debugdpc ); 
  95.          print( "%06X: %04X", debugdpc, iw );
  96.          debugdpc += 2;
  97.          src = (iw & 0x03E0) >> 5;  // Get Source
  98.          dst = (iw & 0x001F);       // Get Destination
  99.  
  100.            print( "%s", dsp_instr[iw >> 10] );    
  101.  
  102.          switch( iw >> 10 )
  103.          {
  104.             // 0 Parameter Instructions 
  105.                case NOP:
  106.                    break;
  107.  
  108.             // 1 Register Parameter Instructions
  109.                case NEG:
  110.                case NOT:
  111.                case RESMAC:
  112.                case ABS:
  113.                case SAT16S:
  114.                case SAT32S:
  115.                case MIRROR:
  116.                    print( "r%02d", dst );  // Just the Destination
  117.                    break;
  118.  
  119.                case MOVE_PC:
  120.                    print( "pc,r%02d", dst ); 
  121.                    break;
  122.  
  123.             // 2 Register Parameter Instructions
  124.                case ADD:
  125.                case ADDC:
  126.                case SUB:
  127.                case SUBC:
  128.                case AND:
  129.                case OR:
  130.                case XOR:
  131.                case MULT:
  132.                case IMULT:
  133.                case IMULTN:
  134.                case IMACN:
  135.                case DIV:
  136.                case SH:
  137.                case SHA:
  138.                case ROR:
  139.                case CMP:
  140.                case MOVE:
  141.                case MOVETA:
  142.                case MOVEFA:
  143.                case MMULT:
  144.                case MTOI:
  145.                case NORMI:
  146.                    print( "r%02d,r%02d", src, dst );
  147.                    break;
  148.  
  149.             // Quick Immediate Instrctions with 1 Register Parameter
  150.                case ADDQ:
  151.                case ADDQT:
  152.                case SUBQ:
  153.                case SUBQT:
  154.                case SHRQ:
  155.                case SHARQ:
  156.                case RORQ:
  157.             case ADDQMOD:
  158.             case SUBQMOD:
  159.                    if( !src ) src = 32;
  160.                    print( "#%02d,r%02d", src, dst );
  161.                    break;
  162.                case SHLQ:
  163.                    print( "#%02d,r%02d", 32 - src, dst );
  164.                    break;
  165.                case BTST:
  166.                case BSET:
  167.                case BCLR:
  168.                case MOVEQ:
  169.                    print( "#%02d,r%02d", src, dst );
  170.                    break;
  171.                case CMPQ:
  172.                    if( src >= 16 ) src -= 32;
  173.                    print( "#%02d,r%02d", src, dst );
  174.                    break;
  175.  
  176.             // Non-Offsetted LOAD
  177.                case LOADB:
  178.                case LOADW:
  179.                case LOAD:
  180.                    print( "(r%02d),r%02d", src, dst );
  181.                    break;
  182.  
  183.             // Non-Offsetted STORE
  184.                case STOREB:
  185.                case STOREW:
  186.                case STORE:
  187.                    print( "r%02d,(r%02d)", dst, src );
  188.                    break;
  189.  
  190.             // Immediate Offset LOAD
  191.                case LOAD_14I:
  192.                case LOAD_15I:
  193.                    ir = ( iw = LOAD_14I ? 14 : 15);
  194.                    if( !src ) src = 32;
  195.                    print( "(r%02d + #%02d),r%02d", ir, src * 4, dst );
  196.                    break;
  197.  
  198.             // Immediate Offset STORE 
  199.                case STORE_14I:
  200.                case STORE_15I:
  201.                    ir = ( iw = STORE_14I ? 14 : 15 );
  202.                    if( !src ) src = 32;
  203.                    print( "r%02d,(r%02d + #%02d)", dst, ir, src * 4 );
  204.                    break;
  205.  
  206.             // Register Offset LOAD
  207.                case LOAD_14R:
  208.                case LOAD_15R:
  209.                    ir = ( iw = LOAD_14R ? 14 : 15 );
  210.                    print( "(r%02d + r%02d),r%02d", ir, src, dst );
  211.                    break;
  212.  
  213.             // Register Offset STORE 
  214.                case STORE_14R:
  215.                case STORE_15R:
  216.                    ir = ( iw = STORE_14R ? 14 : 15 );
  217.                    print( "r%02d,(r%02d + r%02d)", dst, ir, src );
  218.                    break;
  219.  
  220.             // MOVEI Instruction 
  221.                case MOVEI:
  222.                    lsw = mem_readword( debuggpc );
  223.                debugdpc += 2;
  224.                    msw = mem_readword( debuggpc );
  225.                debugdpc += 2;
  226.                    if( lsw < 0 || msw < 0 ) 
  227.                {
  228.                        print( YEL"Insufficient Source Data!!!\n" );
  229.                    } 
  230.                else 
  231.                {
  232.                        movei_long = msw << 16 | lsw;
  233.                        print( "0x%08x,r%02d", movei_long, dst );
  234.                    }                
  235.                    break;
  236.  
  237.             // JUMP Instruction
  238.                case JUMP:
  239.                    if( dst ) print ( "%s,", decode_flags( dst ) );
  240.                    print( "(r%02d)", src );
  241.                    break;
  242.  
  243.             // JR Instruction
  244.                case JR:
  245.                    if( dst ) print( "%s,", decode_flags( dst ) );
  246.                    if( src >= 16 ) src -= 32;
  247.                    printf("$%lx",debuggpc+src*2);
  248.                    break;
  249.  
  250.             default:
  251.                    print( YEL"Illegal DSP Opcode!!!\n" );
  252.                    break;
  253.          }
  254.  
  255.          print( "\n" );
  256.       }
  257.       #endif
  258.    }
  259.  
  260. ////////////////////////////////////////////////////////////////////////////////
  261. // Disassemble GPU Code
  262.  
  263.    void gpudebug_disassemble( int n ) 
  264.    {
  265.       #ifdef DEBUG
  266.       dword iw, src, dst, ir;
  267.        long    msw, lsw;
  268.        long    movei_long;
  269.  
  270.        while( n-- ) 
  271.       {
  272.          iw = mem_readword( debuggpc ); 
  273.          print( "%06X: ", debuggpc );
  274.          debuggpc += 2;
  275.          src = (iw & 0x03E0) >> 5;  // Get Source
  276.          dst = (iw & 0x001F);       // Get Destination
  277.  
  278.            print( "%s", gpu_instr[iw >> 10] );    
  279.  
  280.          switch( iw >> 10 )
  281.          {
  282.             // 0 Parameter Instructions 
  283.                case NOP:
  284.                    break;
  285.  
  286.             // 1 Register Parameter Instructions
  287.                case PACK_UNPACK:
  288.                    if( src )                  // Source is 1 for UNPACK 
  289.                        print( "unpack  " );
  290.                    else
  291.                        print( "pack    " );
  292.                case NEG:
  293.                case NOT:
  294.                case RESMAC:
  295.                case ABS:
  296.                case SAT8:
  297.                case SAT16:
  298.                case SAT24:
  299.                    print( "r%02d", dst );  // Just the Destination
  300.                    break;
  301.  
  302.                case MOVE_PC:
  303.                    print( "pc,r%02d", dst ); 
  304.                    break;
  305.  
  306.             // 2 Register Parameter Instructions
  307.                case ADD:
  308.                case ADDC:
  309.                case SUB:
  310.                case SUBC:
  311.                case AND:
  312.                case OR:
  313.                case XOR:
  314.                case MULT:
  315.                case IMULT:
  316.                case IMULTN:
  317.                case IMACN:
  318.                case DIV:
  319.                case SH:
  320.                case SHA:
  321.                case ROR:
  322.                case CMP:
  323.                case MOVE:
  324.                case MOVETA:
  325.                case MOVEFA:
  326.                case MMULT:
  327.                case MTOI:
  328.                case NORMI:
  329.                    print( "r%02d,r%02d", src, dst );
  330.                    break;
  331.  
  332.             // Quick Immediate Instrctions with 1 Register Parameter
  333.                case ADDQ:
  334.                case ADDQT:
  335.                case SUBQ:
  336.                case SUBQT:
  337.                case SHRQ:
  338.                case SHARQ:
  339.                case RORQ:
  340.                    if( !src ) src = 32;
  341.                    print( "#%02d,r%02d", src, dst );
  342.                    break;
  343.                case SHLQ:
  344.                    print( "#%02d,r%02d", 32 - src, dst );
  345.                    break;
  346.                case BTST:
  347.                case BSET:
  348.                case BCLR:
  349.                case MOVEQ:
  350.                    print( "#%02d,r%02d", src, dst );
  351.                    break;
  352.                case CMPQ:
  353.                    if( src >= 16 ) src -= 32;
  354.                    print( "#%02d,r%02d", src, dst );
  355.                    break;
  356.  
  357.             // Non-Offsetted LOAD
  358.                case LOADB:
  359.                case LOADW:
  360.                case LOAD:
  361.                case LOADP:
  362.                    print( "(r%02d),r%02d", src, dst );
  363.                    break;
  364.  
  365.             // Non-Offsetted STORE
  366.                case STOREB:
  367.                case STOREW:
  368.                case STORE:
  369.                case STOREP:
  370.                    print( "r%02d,(r%02d)", dst, src );
  371.                    break;
  372.  
  373.             // Immediate Offset LOAD
  374.                case LOAD_14I:
  375.                case LOAD_15I:
  376.                    ir = ( iw = LOAD_14I ? 14 : 15);
  377.                    if( !src ) src = 32;
  378.                    print( "(r%02d + #%02d),r%02d", ir, src * 4, dst );
  379.                    break;
  380.  
  381.             // Immediate Offset STORE 
  382.                case STORE_14I:
  383.                case STORE_15I:
  384.                    ir = ( iw = STORE_14I ? 14 : 15 );
  385.                    if( !src ) src = 32;
  386.                    print( "r%02d,(r%02d + #%02d)", dst, ir, src * 4 );
  387.                    break;
  388.  
  389.             // Register Offset LOAD
  390.                case LOAD_14R:
  391.                case LOAD_15R:
  392.                    ir = ( iw = LOAD_14R ? 14 : 15 );
  393.                    print( "(r%02d + r%02d),r%02d", ir, src, dst );
  394.                    break;
  395.  
  396.             // Register Offset STORE 
  397.                case STORE_14R:
  398.                case STORE_15R:
  399.                    ir = ( iw = STORE_14R ? 14 : 15 );
  400.                    print( "r%02d,(r%02d + r%02d)", dst, ir, src );
  401.                    break;
  402.  
  403.             // MOVEI Instruction 
  404.                case MOVEI:
  405.                    lsw = mem_readword( debuggpc );
  406.                debuggpc += 2;
  407.                    msw = mem_readword( debuggpc );
  408.                debuggpc += 2;
  409.                    if( lsw < 0 || msw < 0 ) 
  410.                {
  411.                        print( "Insufficient Source Data\n" );
  412.                    } 
  413.                else 
  414.                {
  415.                        movei_long = msw << 16 | lsw;
  416.                        print( "0x%08x,r%02d", movei_long, dst );
  417.                    }                
  418.                    break;
  419.  
  420.             // JUMP Instruction
  421.                case JUMP:
  422.                    if( dst ) print ( "%s,", decode_flags( dst ) );
  423.                    print( "(r%02d)", src );
  424.                    break;
  425.  
  426.             // JR Instruction
  427.                case JR:
  428.                    if( dst ) print( "%s,", decode_flags( dst ) );
  429.                    if( src >= 16 ) src -= 32;
  430.                    printf("$%lx",debuggpc+src*2);
  431.                    break;
  432.  
  433.             default:
  434.                    print( "**** UNUSED OPCODE %d ****", iw );
  435.                    break;
  436.          }
  437.  
  438.          print( "\n" );
  439.       }
  440.       #endif
  441.    }
  442.  
  443.