Search
lxdream.org :: lxdream/src/sh4/sh4dasm.c
lxdream 0.9.1
released Jun 29
Download Now
filename src/sh4/sh4dasm.c
changeset 9:2784c7660165
prev2:42349f6ea216
next10:c898b37506e0
author nkeynes
date Thu Dec 08 13:38:00 2005 +0000 (15 years ago)
permissions -rw-r--r--
last change Generalise the core debug window to allow multiple instances.
Add cpu description structure to define different cpus for use by the
debug window, in preparation for ARM implementation
view annotate diff log raw
     1 #include "sh4core.h"
     2 #include "sh4dasm.h"
     3 #include "mem.h"
     5 #define UNIMP(ir) snprintf( buf, len, "???     " )
     8 struct reg_desc_struct sh4_reg_map[] = 
     9   { {"R0", REG_INT, &sh4r.r[0]}, {"R1", REG_INT, &sh4r.r[1]},
    10     {"R2", REG_INT, &sh4r.r[2]}, {"R3", REG_INT, &sh4r.r[3]},
    11     {"R4", REG_INT, &sh4r.r[4]}, {"R5", REG_INT, &sh4r.r[5]},
    12     {"R6", REG_INT, &sh4r.r[6]}, {"R7", REG_INT, &sh4r.r[7]},
    13     {"R8", REG_INT, &sh4r.r[8]}, {"R9", REG_INT, &sh4r.r[9]},
    14     {"R10",REG_INT, &sh4r.r[10]}, {"R11",REG_INT, &sh4r.r[11]},
    15     {"R12",REG_INT, &sh4r.r[12]}, {"R13",REG_INT, &sh4r.r[13]},
    16     {"R14",REG_INT, &sh4r.r[14]}, {"R15",REG_INT, &sh4r.r[15]},
    17     {"SR", REG_INT, &sh4r.sr}, {"GBR", REG_INT, &sh4r.gbr},
    18     {"SSR",REG_INT, &sh4r.ssr}, {"SPC", REG_INT, &sh4r.spc},
    19     {"SGR",REG_INT, &sh4r.sgr}, {"DBR", REG_INT, &sh4r.dbr},
    20     {"VBR",REG_INT, &sh4r.vbr},
    21     {"PC", REG_INT, &sh4r.pc}, {"PR", REG_INT, &sh4r.pr},
    22     {"MACL",REG_INT, &sh4r.mac},{"MACH",REG_INT, ((uint32_t *)&sh4r.mac)+1},
    23     {"FPUL", REG_INT, &sh4r.fpul}, {"FPSCR", REG_INT, &sh4r.fpscr},
    24     {NULL, 0, NULL} };
    26 struct cpu_desc_struct sh4_cpu_desc = { "SH4", sh4_disasm_instruction, 2,
    27 					&sh4r, sizeof(sh4r), sh4_reg_map,
    28 					&sh4r.pc, &sh4r.icount };
    30 int sh4_disasm_instruction( int pc, char *buf, int len )
    31 {
    32     uint16_t ir = mem_read_word(pc);
    34 #define RN(ir) ((ir&0x0F00)>>8)
    35 #define RN_BANK(ir) ((ir&0x0070)>>4)
    36 #define RM(ir) ((ir&0x00F0)>>4)
    37 #define DISP4(ir) (ir&0x000F) /* 4-bit displacements are *not* sign extended */
    38 #define DISP8(ir) (ir&0x00FF)
    39 #define PCDISP8(ir) SIGNEXT8(ir&0x00FF)
    40 #define UIMM8(ir) (ir&0x00FF)
    41 #define IMM8(ir) SIGNEXT8(ir&0x00FF)
    42 #define DISP12(ir) SIGNEXT12(ir&0x0FFF)
    43 #define FVN(ir) ((ir&0x0C00)>>10)
    44 #define FVM(ir) ((ir&0x0300)>>8)
    46     switch( (ir&0xF000)>>12 ) {
    47         case 0: /* 0000nnnnmmmmxxxx */
    48             switch( ir&0x000F ) {
    49                 case 2:
    50                     switch( (ir&0x00F0)>>4 ) {
    51                         case 0: snprintf( buf, len, "STC     SR, R%d", RN(ir) ); break;
    52                         case 1: snprintf( buf, len, "STC     GBR, R%d", RN(ir) ); break;
    53                         case 2: snprintf( buf, len, "STC     VBR, R%d", RN(ir) ); break;
    54                         case 3: snprintf( buf, len, "STC     SSR, R%d", RN(ir) ); break;
    55                         case 4: snprintf( buf, len, "STC     SPC, R%d", RN(ir) ); break;
    56                         case 8: case 9: case 10: case 11: case 12: case 13: case 14:
    57                         case 15:snprintf( buf, len, "STC     R%d_bank, R%d", RN_BANK(ir), RN(ir) ); break;
    58                         default: UNIMP(ir);
    59                     }
    60                     break;
    61                 case 3:
    62                     switch( (ir&0x00F0)>>4 ) {
    63                         case 0: snprintf( buf, len, "BSRF    R%d", RN(ir) ); break;
    64                         case 2: snprintf( buf, len, "BRAF    R%d", RN(ir) ); break;
    65                         case 8: snprintf( buf, len, "PREF    [R%d]", RN(ir) ); break;
    66                         case 9: snprintf( buf, len, "OCBI    [R%d]", RN(ir) ); break;
    67                         case 10:snprintf( buf, len, "OCBP    [R%d]", RN(ir) ); break;
    68                         case 11:snprintf( buf, len, "OCBWB   [R%d]", RN(ir) ); break;
    69                         case 12:snprintf( buf, len, "MOVCA.L R0, [R%d]", RN(ir) ); break;
    70                         default: UNIMP(ir);
    71                     }
    72                     break;
    73                 case 4: snprintf( buf, len, "MOV.B   R%d, [R0+R%d]", RM(ir), RN(ir) ); break;
    74                 case 5: snprintf( buf, len, "MOV.W   R%d, [R0+R%d]", RM(ir), RN(ir) ); break;
    75                 case 6: snprintf( buf, len, "MOV.L   R%d, [R0+R%d]", RM(ir), RN(ir) ); break;
    76                 case 7: snprintf( buf, len, "MUL.L   R%d, R%d", RM(ir), RN(ir) ); break;
    77                 case 8:
    78                     switch( (ir&0x0FF0)>>4 ) {
    79                         case 0: snprintf( buf, len, "CLRT    " ); break;
    80                         case 1: snprintf( buf, len, "SETT    " ); break;
    81                         case 2: snprintf( buf, len, "CLRMAC  " ); break;
    82                         case 3: snprintf( buf, len, "LDTLB   " ); break;
    83                         case 4: snprintf( buf, len, "CLRS    " ); break;
    84                         case 5: snprintf( buf, len, "SETS    " ); break;
    85                         default: UNIMP(ir);
    86                     }
    87                     break;
    88                 case 9:
    89                     if( (ir&0x00F0) == 0x20 )
    90                         snprintf( buf, len, "MOVT    R%d", RN(ir) );
    91                     else if( ir == 0x0019 )
    92                         snprintf( buf, len, "DIV0U   " );
    93                     else if( ir == 0x0009 )
    94                         snprintf( buf, len, "NOP     " );
    95                     else UNIMP(ir);
    96                     break;
    97                 case 10:
    98                     switch( (ir&0x00F0) >> 4 ) {
    99                         case 0: snprintf( buf, len, "STS     MACH, R%d", RN(ir) ); break;
   100                         case 1: snprintf( buf, len, "STS     MACL, R%d", RN(ir) ); break;
   101                         case 2: snprintf( buf, len, "STS     PR, R%d", RN(ir) ); break;
   102                         case 3: snprintf( buf, len, "STC     SGR, R%d", RN(ir) ); break;
   103                         case 5: snprintf( buf, len, "STS     FPUL, R%d", RN(ir) ); break;
   104                         case 6: snprintf( buf, len, "STS     FPSCR, R%d", RN(ir) ); break;
   105                         case 15:snprintf( buf, len, "STC     DBR, R%d", RN(ir) ); break;
   106                         default: UNIMP(ir);
   107                     }
   108                     break;
   109                 case 11:
   110                     switch( (ir&0x0FF0)>>4 ) {
   111                         case 0: snprintf( buf, len, "RTS     " ); break;
   112                         case 1: snprintf( buf, len, "SLEEP   " ); break;
   113                         case 2: snprintf( buf, len, "RTE     " ); break;
   114                         default:UNIMP(ir);
   115                     }
   116                     break;
   117                 case 12:snprintf( buf, len, "MOV.B   [R0+R%d], R%d", RM(ir), RN(ir) ); break;
   118                 case 13:snprintf( buf, len, "MOV.W   [R0+R%d], R%d", RM(ir), RN(ir) ); break;
   119                 case 14:snprintf( buf, len, "MOV.L   [R0+R%d], R%d", RM(ir), RN(ir) ); break;
   120                 case 15:snprintf( buf, len, "MAC.L   [R%d++], [R%d++]", RM(ir), RN(ir) ); break;
   121                 default: UNIMP(ir);
   122             }
   123             break;
   124         case 1: /* 0001nnnnmmmmdddd */
   125             snprintf( buf, len, "MOV.L   R%d, [R%d%+d]", RM(ir), RN(ir), DISP4(ir)<<2 ); break;
   126         case 2: /* 0010nnnnmmmmxxxx */
   127             switch( ir&0x000F ) {
   128                 case 0: snprintf( buf, len, "MOV.B   R%d, [R%d]", RM(ir), RN(ir) ); break;
   129                 case 1: snprintf( buf, len, "MOV.W   R%d, [R%d]", RM(ir), RN(ir) ); break;
   130                 case 2: snprintf( buf, len, "MOV.L   R%d, [R%d]", RM(ir), RN(ir) ); break;
   131                 case 3: UNIMP(ir); break;
   132                 case 4: snprintf( buf, len, "MOV.B   R%d, [--R%d]", RM(ir), RN(ir) ); break;
   133                 case 5: snprintf( buf, len, "MOV.W   R%d, [--R%d]", RM(ir), RN(ir) ); break;
   134                 case 6: snprintf( buf, len, "MOV.L   R%d, [--R%d]", RM(ir), RN(ir) ); break;
   135                 case 7: snprintf( buf, len, "DIV0S   R%d, R%d", RM(ir), RN(ir) ); break;
   136                 case 8: snprintf( buf, len, "TST     R%d, R%d", RM(ir), RN(ir) ); break;
   137                 case 9: snprintf( buf, len, "AND     R%d, R%d", RM(ir), RN(ir) ); break;
   138                 case 10:snprintf( buf, len, "XOR     R%d, R%d", RM(ir), RN(ir) ); break;
   139                 case 11:snprintf( buf, len, "OR      R%d, R%d", RM(ir), RN(ir) ); break;
   140                 case 12:snprintf( buf, len, "CMP/STR R%d, R%d", RM(ir), RN(ir) ); break;
   141                 case 13:snprintf( buf, len, "XTRCT   R%d, R%d", RM(ir), RN(ir) ); break;
   142                 case 14:snprintf( buf, len, "MULU.W  R%d, R%d", RM(ir), RN(ir) ); break;
   143                 case 15:snprintf( buf, len, "MULS.W  R%d, R%d", RM(ir), RN(ir) ); break;
   144             }
   145             break;
   146         case 3: /* 0011nnnnmmmmxxxx */
   147             switch( ir&0x000F ) {
   148                 case 0: snprintf( buf, len, "CMP/EQ  R%d, R%d", RM(ir), RN(ir) ); break;
   149                 case 2: snprintf( buf, len, "CMP/HS  R%d, R%d", RM(ir), RN(ir) ); break;
   150                 case 3: snprintf( buf, len, "CMP/GE  R%d, R%d", RM(ir), RN(ir) ); break;
   151                 case 4: snprintf( buf, len, "DIV1    R%d, R%d", RM(ir), RN(ir) ); break;
   152                 case 5: snprintf( buf, len, "DMULU.L R%d, R%d", RM(ir), RN(ir) ); break;
   153                 case 6: snprintf( buf, len, "CMP/HI  R%d, R%d", RM(ir), RN(ir) ); break;
   154                 case 7: snprintf( buf, len, "CMP/GT  R%d, R%d", RM(ir), RN(ir) ); break;
   155                 case 8: snprintf( buf, len, "SUB     R%d, R%d", RM(ir), RN(ir) ); break;
   156                 case 10:snprintf( buf, len, "SUBC    R%d, R%d", RM(ir), RN(ir) ); break;
   157                 case 11:snprintf( buf, len, "SUBV    R%d, R%d", RM(ir), RN(ir) ); break;
   158                 case 12:snprintf( buf, len, "ADD     R%d, R%d", RM(ir), RN(ir) ); break;
   159                 case 13:snprintf( buf, len, "DMULS.L R%d, R%d", RM(ir), RN(ir) ); break;
   160                 case 14:snprintf( buf, len, "ADDC    R%d, R%d", RM(ir), RN(ir) ); break;
   161                 case 15:snprintf( buf, len, "ADDV    R%d, R%d", RM(ir), RN(ir) ); break;
   162                 default: UNIMP(ir);
   163             }
   164             break;
   165         case 4: /* 0100nnnnxxxxxxxx */
   166             switch( ir&0x00FF ) {
   167                 case 0x00: snprintf( buf, len, "SHLL    R%d", RN(ir) ); break;
   168                 case 0x01: snprintf( buf, len, "SHLR    R%d", RN(ir) ); break;
   169                 case 0x02: snprintf( buf, len, "STS.L   MACH, [--R%d]", RN(ir) ); break;
   170                 case 0x03: snprintf( buf, len, "STC.L   SR, [--R%d]", RN(ir) ); break;
   171                 case 0x04: snprintf( buf, len, "ROTL    R%d", RN(ir) ); break;
   172                 case 0x05: snprintf( buf, len, "ROTR    R%d", RN(ir) ); break;
   173                 case 0x06: snprintf( buf, len, "LDS.L   [R%d++], MACH", RN(ir) ); break;
   174                 case 0x07: snprintf( buf, len, "LDC.L   [R%d++], SR", RN(ir) ); break;
   175                 case 0x08: snprintf( buf, len, "SHLL2   R%d", RN(ir) ); break;
   176                 case 0x09: snprintf( buf, len, "SHLR2   R%d", RN(ir) ); break;
   177                 case 0x0A: snprintf( buf, len, "LDS     R%d, MACH", RN(ir) ); break;
   178                 case 0x0B: snprintf( buf, len, "JSR     [R%d]", RN(ir) ); break;
   179                 case 0x0E: snprintf( buf, len, "LDC     R%d, SR", RN(ir) ); break;
   180                 case 0x10: snprintf( buf, len, "DT      R%d", RN(ir) ); break;
   181                 case 0x11: snprintf( buf, len, "CMP/PZ  R%d", RN(ir) ); break;
   182                 case 0x12: snprintf( buf, len, "STS.L   MACL, [--R%d]", RN(ir) ); break;
   183                 case 0x13: snprintf( buf, len, "STC.L   GBR, [--R%d]", RN(ir) ); break;
   184                 case 0x15: snprintf( buf, len, "CMP/PL  R%d", RN(ir) ); break;
   185                 case 0x16: snprintf( buf, len, "LDS.L   [R%d++], MACL", RN(ir) ); break;
   186                 case 0x17: snprintf( buf, len, "LDC.L   [R%d++], GBR", RN(ir) ); break;
   187                 case 0x18: snprintf( buf, len, "SHLL8   R%d", RN(ir) ); break;
   188                 case 0x19: snprintf( buf, len, "SHLR8   R%d", RN(ir) ); break;
   189                 case 0x1A: snprintf( buf, len, "LDS     R%d, MACL", RN(ir) ); break;
   190                 case 0x1B: snprintf( buf, len, "TAS.B   [R%d]", RN(ir) ); break;
   191                 case 0x1E: snprintf( buf, len, "LDC     R%d, GBR", RN(ir) ); break;
   192                 case 0x20: snprintf( buf, len, "SHAL    R%d", RN(ir) ); break;
   193                 case 0x21: snprintf( buf, len, "SHAR    R%d", RN(ir) ); break;
   194                 case 0x22: snprintf( buf, len, "STS.L   PR, [--R%d]", RN(ir) ); break;
   195                 case 0x23: snprintf( buf, len, "STC.L   VBR, [--R%d]", RN(ir) ); break;
   196                 case 0x24: snprintf( buf, len, "ROTCL   R%d", RN(ir) ); break;
   197                 case 0x25: snprintf( buf, len, "ROTCR   R%d", RN(ir) ); break;
   198                 case 0x26: snprintf( buf, len, "LDS.L   [R%d++], PR", RN(ir) ); break;
   199                 case 0x27: snprintf( buf, len, "LDC.L   [R%d++], VBR", RN(ir) ); break;
   200                 case 0x28: snprintf( buf, len, "SHLL16  R%d", RN(ir) ); break;
   201                 case 0x29: snprintf( buf, len, "SHLR16  R%d", RN(ir) ); break;
   202                 case 0x2A: snprintf( buf, len, "LDS     R%d, PR", RN(ir) ); break;
   203                 case 0x2B: snprintf( buf, len, "JMP     [R%d]", RN(ir) ); break;
   204                 case 0x2E: snprintf( buf, len, "LDC     R%d, VBR", RN(ir) ); break;
   205                 case 0x32: snprintf( buf, len, "STC.L   SGR, [--R%d]", RN(ir) ); break;
   206                 case 0x33: snprintf( buf, len, "STC.L   SSR, [--R%d]", RN(ir) ); break;
   207                 case 0x37: snprintf( buf, len, "LDC.L   [R%d++], SSR", RN(ir) ); break;
   208                 case 0x3E: snprintf( buf, len, "LDC     R%d, SSR", RN(ir) ); break;
   209                 case 0x43: snprintf( buf, len, "STC.L   SPC, [--R%d]", RN(ir) ); break;
   210                 case 0x47: snprintf( buf, len, "LDC.L   [R%d++], SPC", RN(ir) ); break;
   211                 case 0x4E: snprintf( buf, len, "LDC     R%d, SPC", RN(ir) ); break;
   212                 case 0x52: snprintf( buf, len, "STS.L   FPUL, [--R%d]", RN(ir) ); break;
   213                 case 0x56: snprintf( buf, len, "LDS.L   [R%d++], FPUL", RN(ir) ); break;
   214                 case 0x5A: snprintf( buf, len, "LDS     R%d, FPUL", RN(ir) ); break;
   215                 case 0x62: snprintf( buf, len, "STS.L   FPSCR, [--R%d]", RN(ir) ); break;
   216                 case 0x66: snprintf( buf, len, "LDS.L   [R%d++], FPSCR", RN(ir) ); break;
   217                 case 0x6A: snprintf( buf, len, "LDS     R%d, FPSCR", RN(ir) ); break;
   218                 case 0xF2: snprintf( buf, len, "STC.L   DBR, [--R%d]", RN(ir) ); break;
   219                 case 0xF6: snprintf( buf, len, "LDC.L   [R%d++], DBR", RN(ir) ); break;
   220                 case 0xFA: snprintf( buf, len, "LDC     R%d, DBR", RN(ir) ); break;
   221                 case 0x83: case 0x93: case 0xA3: case 0xB3: case 0xC3: case 0xD3: case 0xE3:
   222                 case 0xF3: snprintf( buf, len, "STC.L   R%d_BANK, [--R%d]", RN_BANK(ir), RN(ir) ); break;
   223                 case 0x87: case 0x97: case 0xA7: case 0xB7: case 0xC7: case 0xD7: case 0xE7:
   224                 case 0xF7: snprintf( buf, len, "LDC.L   [R%d++], R%d_BANK", RN(ir), RN_BANK(ir) ); break; 
   225                 case 0x8E: case 0x9E: case 0xAE: case 0xBE: case 0xCE: case 0xDE: case 0xEE:
   226                 case 0xFE: snprintf( buf, len, "LDC     R%d, R%d_BANK", RN(ir), RN_BANK(ir) ); break;
   227                 default:
   228                     if( (ir&0x000F) == 0x0F ) {
   229                         snprintf( buf, len, "MAC.W   [R%d++], [R%d++]", RM(ir), RN(ir) );
   230                     } else if( (ir&0x000F) == 0x0C ) {
   231                         snprintf( buf, len, "SHAD    R%d, R%d", RM(ir), RN(ir) );
   232                     } else if( (ir&0x000F) == 0x0D ) {
   233                         snprintf( buf, len, "SHLD    R%d, R%d", RM(ir), RN(ir) );
   234                     } else UNIMP(ir);
   235             }
   236             break;
   237         case 5: /* 0101nnnnmmmmdddd */
   238             snprintf( buf, len, "MOV.L   [R%d%+d], R%d", RM(ir), DISP4(ir)<<2, RN(ir) ); break;
   239         case 6: /* 0110xxxxxxxxxxxx */
   240             switch( ir&0x000f ) {
   241                 case 0: snprintf( buf, len, "MOV.B   [R%d], R%d", RM(ir), RN(ir) ); break;
   242                 case 1: snprintf( buf, len, "MOV.W   [R%d], R%d", RM(ir), RN(ir) ); break;
   243                 case 2: snprintf( buf, len, "MOV.L   [R%d], R%d", RM(ir), RN(ir) ); break;
   244                 case 3: snprintf( buf, len, "MOV     R%d, R%d", RM(ir), RN(ir) );   break;
   245                 case 4: snprintf( buf, len, "MOV.B   [R%d++], R%d", RM(ir), RN(ir) ); break;
   246                 case 5: snprintf( buf, len, "MOV.W   [R%d++], R%d", RM(ir), RN(ir) ); break;
   247                 case 6: snprintf( buf, len, "MOV.L   [R%d++], R%d", RM(ir), RN(ir) ); break;
   248                 case 7: snprintf( buf, len, "NOT     R%d, R%d", RM(ir), RN(ir) ); break;
   249                 case 8: snprintf( buf, len, "SWAP.B  R%d, R%d", RM(ir), RN(ir) ); break;
   250                 case 9: snprintf( buf, len, "SWAP.W  R%d, R%d", RM(ir), RN(ir) ); break;
   251                 case 10:snprintf( buf, len, "NEGC    R%d, R%d", RM(ir), RN(ir) ); break;
   252                 case 11:snprintf( buf, len, "NEG     R%d, R%d", RM(ir), RN(ir) ); break;
   253                 case 12:snprintf( buf, len, "EXTU.B  R%d, R%d", RM(ir), RN(ir) ); break;
   254                 case 13:snprintf( buf, len, "EXTU.W  R%d, R%d", RM(ir), RN(ir) ); break;
   255                 case 14:snprintf( buf, len, "EXTS.B  R%d, R%d", RM(ir), RN(ir) ); break;
   256                 case 15:snprintf( buf, len, "EXTS.W  R%d, R%d", RM(ir), RN(ir) ); break;
   257             }
   258             break;
   259         case 7: /* 0111nnnniiiiiiii */
   260             snprintf( buf, len, "ADD    #%d, R%d", SIGNEXT8(ir&0x00FF), RN(ir) ); break;
   261         case 8: /* 1000xxxxxxxxxxxx */
   262             switch( (ir&0x0F00) >> 8 ) {
   263                 case 0: snprintf( buf, len, "MOV.B   R0, [R%d%+d]", RM(ir), DISP4(ir) ); break;
   264                 case 1: snprintf( buf, len, "MOV.W   R0, [R%d%+d]", RM(ir), DISP4(ir)<<1 ); break;
   265                 case 4: snprintf( buf, len, "MOV.B   [R%d%+d], R0", RM(ir), DISP4(ir) ); break;
   266                 case 5: snprintf( buf, len, "MOV.W   [R%d%+d], R0", RM(ir), DISP4(ir)<<1 ); break;
   267                 case 8: snprintf( buf, len, "CMP/EQ  #%d, R0", IMM8(ir) ); break;
   268                 case 9: snprintf( buf, len, "BT      $%xh", (PCDISP8(ir)<<1)+pc+4 ); break;
   269                 case 11:snprintf( buf, len, "BF      $%xh", (PCDISP8(ir)<<1)+pc+4 ); break;
   270                 case 13:snprintf( buf, len, "BT/S    $%xh", (PCDISP8(ir)<<1)+pc+4 ); break;
   271                 case 15:snprintf( buf, len, "BF/S    $%xh", (PCDISP8(ir)<<1)+pc+4 ); break;
   272                 default: UNIMP(ir);
   273             }
   274             break;
   275         case 9: /* 1001xxxxxxxxxxxx */
   276             snprintf( buf, len, "MOV.W   [$%xh], R%-2d ; <- #%08x", (DISP8(ir)<<1)+pc+4, RN(ir),
   277                       mem_read_word( (DISP8(ir)<<1)+pc+4 ) ); break;
   278         case 10:/* 1010xxxxxxxxxxxx */
   279             snprintf( buf, len, "BRA     $%xh", (DISP12(ir)<<1)+pc+4 ); break;
   280         case 11:/* 1011xxxxxxxxxxxx */
   281             snprintf( buf, len, "BSR     $%xh", (DISP12(ir)<<1)+pc+4 ); break;            
   282         case 12:/* 1100xxxxdddddddd */
   283             switch( (ir&0x0F00)>>8 ) {
   284                 case 0: snprintf( buf, len, "MOV.B   R0, [GBR%+d]", DISP8(ir) ); break;
   285                 case 1: snprintf( buf, len, "MOV.W   R0, [GBR%+d]", DISP8(ir)<<1 ); break;
   286                 case 2: snprintf( buf, len, "MOV.L   R0, [GBR%+d]", DISP8(ir)<<2 ); break;
   287                 case 3: snprintf( buf, len, "TRAPA   #%d", UIMM8(ir) ); break;
   288                 case 4: snprintf( buf, len, "MOV.B   [GBR%+d], R0", DISP8(ir) ); break;
   289                 case 5: snprintf( buf, len, "MOV.W   [GBR%+d], R0", DISP8(ir)<<1 ); break;
   290                 case 6: snprintf( buf, len, "MOV.L   [GBR%+d], R0", DISP8(ir)<<2 ); break;
   291                 case 7: snprintf( buf, len, "MOVA    $%xh, R0", (DISP8(ir)<<2)+(pc&~3)+4 ); break;
   292                 case 8: snprintf( buf, len, "TST     #%02Xh, R0", UIMM8(ir) ); break;
   293                 case 9: snprintf( buf, len, "AND     #%02Xh, R0", UIMM8(ir) ); break;
   294                 case 10:snprintf( buf, len, "XOR     #%02Xh, R0", UIMM8(ir) ); break;
   295                 case 11:snprintf( buf, len, "OR      #%02Xh, R0", UIMM8(ir) ); break;
   296                 case 12:snprintf( buf, len, "TST.B   #%02Xh, [R0+GBR]", UIMM8(ir) ); break;
   297                 case 13:snprintf( buf, len, "AND.B   #%02Xh, [R0+GBR]", UIMM8(ir) ); break;
   298                 case 14:snprintf( buf, len, "XOR.B   #%02Xh, [R0+GBR]", UIMM8(ir) ); break;
   299                 case 15:snprintf( buf, len, "OR.B    #%02Xh, [R0+GBR]", UIMM8(ir) ); break;
   300             }
   301             break;
   302         case 13:/* 1101xxxxxxxxxxxx */
   303             snprintf( buf, len, "MOV.L   [$%xh], R%-2d ; <- #%08x", (DISP8(ir)<<2)+(pc&~3)+4, RN(ir),
   304                       mem_read_long( (DISP8(ir)<<2)+(pc&~3)+4 ) ); break;
   305         case 14:/* 1110xxxxxxxxxxxx */
   306             snprintf( buf, len, "MOV     #%d, R%d", DISP8(ir), RN(ir)); break;
   307         case 15:/* 1111xxxxxxxxxxxx */
   308             switch( ir&0x000F ) {
   309                 case 0: snprintf( buf, len, "FADD    FR%d, FR%d", RM(ir), RN(ir) ); break;
   310                 case 1: snprintf( buf, len, "FSUB    FR%d, FR%d", RM(ir), RN(ir) ); break;
   311                 case 2: snprintf( buf, len, "FMUL    FR%d, FR%d", RM(ir), RN(ir) ); break;
   312                 case 3: snprintf( buf, len, "FDIV    FR%d, FR%d", RM(ir), RN(ir) ); break;
   313                 case 4: snprintf( buf, len, "FCMP/EQ FR%d, FR%d", RM(ir), RN(ir) ); break;
   314                 case 5: snprintf( buf, len, "FCMP/GT FR%d, FR%d", RM(ir), RN(ir) ); break;
   315                 case 6: snprintf( buf, len, "FMOV.S  [R%d+R0], FR%d", RM(ir), RN(ir) ); break;
   316                 case 7: snprintf( buf, len, "FMOV.S  FR%d, [R%d+R0]", RM(ir), RN(ir) ); break;
   317                 case 8: snprintf( buf, len, "FMOV.S  [R%d], FR%d", RM(ir), RN(ir) ); break;
   318                 case 9: snprintf( buf, len, "FMOV.S  [R%d++], FR%d", RM(ir), RN(ir) ); break;
   319                 case 10:snprintf( buf, len, "FMOV.S  FR%d, [R%d]", RM(ir), RN(ir) ); break;
   320                 case 11:snprintf( buf, len, "FMOV.S  FR%d, [--R%d]", RM(ir), RN(ir) ); break;
   321                 case 12:snprintf( buf, len, "FMOV    FR%d, FR%d", RM(ir), RN(ir) ); break;
   322                 case 13:
   323                     switch( (ir&0x00F0) >> 4 ) {
   324                         case 0: snprintf( buf, len, "FSTS    FPUL, FR%d", RN(ir) ); break;
   325                         case 1: snprintf( buf, len, "FLDS    FR%d, FPUL", RN(ir) ); break;
   326                         case 2: snprintf( buf, len, "FLOAT   FPUL, FR%d", RN(ir) ); break;
   327                         case 3: snprintf( buf, len, "FTRC    FR%d, FPUL", RN(ir) ); break;
   328                         case 4: snprintf( buf, len, "FNEG    FR%d", RN(ir) ); break;
   329                         case 5: snprintf( buf, len, "FABS    FR%d", RN(ir) ); break;
   330                         case 6: snprintf( buf, len, "FSQRT   FR%d", RN(ir) ); break;
   331                         case 7: snprintf( buf, len, "FSRRA   FR%d", RN(ir) ); break;
   332                         case 8: snprintf( buf, len, "FLDI0   FR%d", RN(ir) ); break;
   333                         case 9: snprintf( buf, len, "FLDI1   FR%d", RN(ir) ); break;
   334                         case 10:snprintf( buf, len, "FCNVSD  FPUL, DR%d", RN(ir)>>1 ); break;
   335                         case 11:snprintf( buf, len, "FCNVDS  DR%d, FPUL", RN(ir)>>1 ); break;
   336                         case 14:snprintf( buf, len, "FIPR    FV%d, FV%d", FVM(ir), FVN(ir) ); break;
   337                         case 15:
   338                             if( (ir & 0x0300) == 0x0100 )
   339                                 snprintf( buf, len, "FTRV    XMTRX,FV%d", FVN(ir) );
   340                             else if( (ir & 0x0100) == 0 )
   341                                 snprintf( buf, len, "FSCA    FPUL, DR%d", RN(ir) );
   342                             else if( ir == 0xFBFD )
   343                                 snprintf( buf, len, "FRCHG   " );
   344                             else if( ir == 0xF3FD )
   345                                 snprintf( buf, len, "FSCHG   " );
   346                             else UNIMP(ir);
   347                             break;
   348                         default: UNIMP(ir);
   349                     }
   350                     break;
   351                 case 14:snprintf( buf, len, "FMAC    FR0, FR%d, FR%d", RM(ir), RN(ir) ); break;
   352                 default: UNIMP(ir);
   353             }
   354             break;
   355     }
   356     return pc+2;
   357 }
   360 void sh4_disasm_region( FILE *f, int from, int to, int load_addr )
   361 {
   362     int pc;
   363     char buf[80];
   365     for( pc = from; pc < to; pc+=2 ) {
   366         uint16_t op = mem_read_word( pc );
   367         buf[0] = '\0';
   368         sh4_disasm_instruction( pc,
   369                                 buf, sizeof(buf) );
   370         fprintf( f, "  %08x:  %04x  %s\n", pc + load_addr, op, buf );
   371     }
   372 }
.