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