/**************************************************************************\ * Texas Instruments TMS320x25 DSP Disassembler * * * * Copyright (C) 2001-2002+ Tony La Porta * * To be used with TMS320x25 DSP Emulator engine. * * Written for the MAME project. * * * * Many thanks to those involved in the i8039 Disassembler * * as the structure here was borrowed from it. * * * * Note : This is a word based microcontroller, with addressing * * architecture based on the Harvard addressing scheme. * * * * * * A Memory Address * * B Opcode Address Argument (Requires next opcode read) * * C Compare mode * * D Immediate byte load * * K Immediate bit load * * W Immediate word load * * M AR[x] register modification type (for indirect addressing) * * N ARP register to change ARP pointer to (for indirect addressing) * * P I/O port address number * * R AR[R] register to use * * S Shift ALU left * * T Shift ALU left (Hex) / Nibble data * * X Don't care bit * * * \**************************************************************************/ #include #include #include #include #ifdef MAME_DEBUG /* Compile interface to MAME */ #include "tms32025.h" #include "debugger.h" extern UINT16 *tms32025_pgmmap[0x200]; //#define READOP16(A) (cpu_readop16((A) | (TMS32025_PGM_OFFSET << 1))) //#define READARG16(A) (cpu_readop_arg16((A) | (TMS32025_PGM_OFFSET << 1))) #define READOP16(A) ((tms32025_pgmmap[(A) >> 7]) ? (tms32025_pgmmap[(A) >> 7][(A) & 0x7f]) : cpu_readop16((A)<<1)) #define READARG16(A) ((tms32025_pgmmap[(A) >> 7]) ? (tms32025_pgmmap[(A) >> 7][(A) & 0x7f]) : cpu_readop16((A)<<1)) #else /* Compile interface for standalone */ extern unsigned char *Buffer; #ifdef MSB_FIRST #define READOP16(A) ( ((Buffer[A+1]<<8) | Buffer[A]) ) #define READARG16(A) ( ((Buffer[A+1]<<8) | Buffer[A]) ) #else #define READOP16(A) ( ((Buffer[A]<<8) | Buffer[A+1]) ) #define READARG16(A) ( ((Buffer[A]<<8) | Buffer[A+1]) ) #endif #endif typedef unsigned char byte; typedef unsigned short int word; #define FMT(a,b) a, b #define PTRS_PER_FORMAT 2 static const char *arith[8] = { "*", "*-", "*+", "??", "BR0-", "*0-", "*0+", "*BR0+" } ; static const char *nextar[16] = { "", "", "", "", "", "", "", "", ",AR0", ",AR1", ",AR2", ",AR3", ",AR4", ",AR5", ",AR6", ",AR7" } ; static const char *cmpmode[4] = { "0 (ARx = AR0)" , "1 (ARx < AR0)" , "2 (ARx > AR0)" , "3 (ARx <> AR0)" } ; static const char *TMS32025Formats[] = { FMT("0000tttt0aaaaaaa", "add %A,%T"), /* 0xxx */ FMT("0000tttt1mmmnnnn", "add %M,%T%N"), FMT("0001tttt0aaaaaaa", "sub %A,%T"), /* 1xxx */ FMT("0001tttt1mmmnnnn", "sub %M,%T%N"), FMT("0010tttt0aaaaaaa", "lac %A,%T"), /* 2xxx */ FMT("0010tttt1mmmnnnn", "lac %M,%T%N"), FMT("00110rrr0aaaaaaa", "lar %R,%A"), /* 3xxx */ FMT("00110rrr1mmmnnnn", "lar %R%M%N"), FMT("001110000aaaaaaa", "mpy %A"), /* 38xx */ FMT("001110001mmmnnnn", "mpy %M%N"), FMT("001110010aaaaaaa", "sqra %A"), /* 39xx */ FMT("001110011mmmnnnn", "sqra %M%N"), FMT("001110100aaaaaaa", "mpya %A"), /* 3Axx */ FMT("001110101mmmnnnn", "mpya %M%N"), FMT("001110110aaaaaaa", "mpys %A"), /* 3Bxx */ FMT("001110111mmmnnnn", "mpys %M%N"), FMT("001111000aaaaaaa", "lt %A"), /* 3Cxx */ FMT("001111001mmmnnnn", "lt %M%N"), FMT("001111010aaaaaaa", "lta %A"), /* 3Dxx */ FMT("001111011mmmnnnn", "lta %M%N"), FMT("001111100aaaaaaa", "ltp %A"), /* 3Exx */ FMT("001111101mmmnnnn", "ltp %M%N"), FMT("001111110aaaaaaa", "ltd %A"), /* 3Fxx */ FMT("001111111mmmnnnn", "ltd %M%N"), FMT("010000000aaaaaaa", "zalh %A"), /* 40xx */ FMT("010000001mmmnnnn", "zalh %M%N"), FMT("010000010aaaaaaa", "zals %A"), /* 41xx */ FMT("010000011mmmnnnn", "zals %M%N"), FMT("010000100aaaaaaa", "lact %A"), /* 42xx */ FMT("010000101mmmnnnn", "lact %M%N"), FMT("010000110aaaaaaa", "addc %A%S"), /* 43xx */ FMT("010000111mmmnnnn", "addc %M%S%N"), FMT("010001000aaaaaaa", "subh %A"), /* 44xx */ FMT("010001001mmmnnnn", "subh %M%N"), FMT("010001010aaaaaaa", "subs %A"), /* 45xx */ FMT("010001011mmmnnnn", "subs %M%N"), FMT("010001100aaaaaaa", "subt %A"), /* 46xx */ FMT("010001101mmmnnnn", "subt %M%N"), FMT("010001110aaaaaaa", "subc %A"), /* 47xx */ FMT("010001111mmmnnnn", "subc %M%N"), FMT("010010000aaaaaaa", "addh %A"), /* 48xx */ FMT("010010001mmmnnnn", "addh %M%N"), FMT("010010010aaaaaaa", "adds %A"), /* 49xx */ FMT("010010011mmmnnnn", "adds %M%N"), FMT("010010100aaaaaaa", "addt %A"), /* 4Axx */ FMT("010010101mmmnnnn", "addt %M%N"), FMT("010010110aaaaaaa", "rpt %A"), /* 4Bxx */ FMT("010010111mmmnnnn", "rpt %M%N"), FMT("010011000aaaaaaa", "xor %A"), /* 4Cxx */ FMT("010011001mmmnnnn", "xor %M%N"), FMT("010011010aaaaaaa", "or %A"), /* 4Dxx */ FMT("010011011mmmnnnn", "or %M%N"), FMT("010011100aaaaaaa", "and %A"), /* 4Exx */ FMT("010011101mmmnnnn", "and %M%N"), FMT("010011110aaaaaaa", "subb %A"), /* 4Fxx */ FMT("010011111mmmnnnn", "subb %M%N"), FMT("010100000aaaaaaa", "lst %A"), /* 50xx */ FMT("010100001mmmnnnn", "lst %M%N"), FMT("010100010aaaaaaa", "lst1 %A"), /* 51xx */ FMT("010100011mmmnnnn", "lst1 %M%N"), FMT("010100100aaaaaaa", "ldp %A"), /* 52xx */ FMT("010100101mmmnnnn", "ldp %M%N"), FMT("010100110aaaaaaa", "lph %A"), /* 53xx */ FMT("010100111mmmnnnn", "lph %M%N"), FMT("010101000aaaaaaa", "pshd %A"), /* 54xx */ FMT("010101001mmmnnnn", "pshd %M%N"), /* FMT("010101010aaaaaaa", "mar %A"), 55xx */ /* MAR direct has been expanded out to all its variations because one of its */ /* its opcodes is the same as NOP. Actually MAR direct just performs a NOP */ FMT("0101010100000000", "nop"), /* 5500 */ FMT("0101010100000001", "mar $01"), FMT("0101010100000010", "mar $02"), FMT("0101010100000011", "mar $03"), FMT("0101010100000100", "mar $04"), FMT("0101010100000101", "mar $05"), FMT("0101010100000110", "mar $06"), FMT("0101010100000111", "mar $07"), FMT("0101010100001000", "mar $08"), FMT("0101010100001001", "mar $09"), FMT("0101010100001010", "mar $0A"), FMT("0101010100001011", "mar $0B"), FMT("0101010100001100", "mar $0C"), FMT("0101010100001101", "mar $0D"), FMT("0101010100001110", "mar $0E"), FMT("0101010100001111", "mar $0F"), FMT("010101010001tttt", "mar $1%T"), FMT("010101010010tttt", "mar $2%T"), FMT("010101010011tttt", "mar $3%T"), FMT("010101010100tttt", "mar $4%T"), FMT("010101010101tttt", "mar $5%T"), FMT("010101010110tttt", "mar $6%T"), FMT("010101010111tttt", "mar $7%T"), /* FMT("010101011mmmnnnn", "mar %M%N"), 55xx */ /* MAR indirect has been expanded out to all its variations because one of */ /* its opcodes, is the same as LARP (actually performs the same function) */ FMT("0101010110000xxx", "mar *"), /* 558x */ FMT("0101010110001kkk", "larp %K"), /* 558x */ FMT("010101011001nnnn", "mar *-%N"), /* 558x */ FMT("010101011010nnnn", "mar *+%N"), FMT("010101011011nnnn", "mar ??%N"), FMT("010101011100nnnn", "mar *BR0-%N"), FMT("010101011101nnnn", "mar *0-%N"), FMT("010101011110nnnn", "mar *0+%N"), FMT("010101011111nnnn", "mar *BR0+%N"), FMT("010101100aaaaaaa", "dmov %A"), /* 56xx */ FMT("010101101mmmnnnn", "dmov %M%N"), FMT("010101110aaaaaaa", "bitt %A"), /* 57xx */ FMT("010101111mmmnnnn", "bitt %M%N"), FMT("010110000aaaaaaa", "tblr %A"), /* 58xx */ FMT("010110001mmmnnnn", "tblr %M%N"), FMT("010110010aaaaaaa", "tblw %A"), /* 59xx */ FMT("010110011mmmnnnn", "tblw %M%N"), FMT("010110100aaaaaaa", "sqrs %A"), /* 5Axx */ FMT("010110101mmmnnnn", "sqrs %M%N"), FMT("010110110aaaaaaa", "lts %A"), /* 5Bxx */ FMT("010110111mmmnnnn", "lts %M%N"), FMT("010111000aaaaaaabbbbbbbbbbbbbbbb", "macd %B,%A"), /* 5Cxx */ FMT("010111001mmmnnnnbbbbbbbbbbbbbbbb", "macd %B,%M%N"), FMT("010111010aaaaaaabbbbbbbbbbbbbbbb", "mac %B,%A"), /* 5Dxx */ FMT("010111011mmmnnnnbbbbbbbbbbbbbbbb", "mac %B,%M%N"), FMT("010111101mmmnnnnbbbbbbbbbbbbbbbb", "bc %B %M%N"), /* 5Exx */ FMT("010111111mmmnnnnbbbbbbbbbbbbbbbb", "bnc %B %M%N"), /* 5Fxx */ FMT("01100sss0aaaaaaa", "sacl %A%S"), /* 6xxx */ FMT("01100sss1mmmnnnn", "sacl %M%S%N"), FMT("01101sss0aaaaaaa", "sach %A%S"), /* 6Xxx */ FMT("01101sss1mmmnnnn", "sach %M%S%N"), FMT("01110rrr0aaaaaaa", "sar %R,%A"), /* 7xxx */ FMT("01110rrr1mmmnnnn", "sar %R%M%N"), FMT("011110000aaaaaaa", "sst %A"), /* 78xx */ FMT("011110001mmmnnnn", "sst %M%N"), FMT("011110010aaaaaaa", "sst1 %A"), /* 79xx */ FMT("011110011mmmnnnn", "sst1 %M%N"), FMT("011110100aaaaaaa", "popd %A"), /* 7Axx */ FMT("011110101mmmnnnn", "popd %M%N"), FMT("011110110aaaaaaa", "zalr %A"), /* 7Bxx */ FMT("011110111mmmnnnn", "zalr %M%N"), FMT("011111000aaaaaaa", "spl %A"), /* 7Cxx */ FMT("011111001mmmnnnn", "spl %M%N"), FMT("011111010aaaaaaa", "sph %A"), /* 7Dxx */ FMT("011111011mmmnnnn", "sph %M%N"), FMT("011111100aaaaaaa", "adrk %A"), /* 7Exx */ FMT("011111101mmmnnnn", "adrk %M%N"), FMT("011111110aaaaaaa", "sbrk %A"), /* 7Fxx */ FMT("011111111mmmnnnn", "sbrk %M%N"), FMT("1000pppp0aaaaaaa", "in %A,%P"), /* 8xxx */ FMT("1000pppp1mmmnnnn", "in %M,%P%N"), FMT("1001tttt0aaaaaaa", "bit %A,%T"), /* 9xxx */ FMT("1001tttt1mmmnnnn", "bit %M,%T%N"), FMT("101wwwwwwwwwwwww", "mpyk %W"), /* Axxx-Bxxx */ FMT("11000rrrdddddddd", "lark %R,%D"), /* Cxxx */ FMT("1100100kdddddddd", "ldpk %K%D"), /* Cxxx */ /* FMT("11001010dddddddd", "lack %D"), CAxx */ /* LACK has been expanded out to all its variations because one of its */ /* its opcodes is the same as ZAC. Actually, it performs the same function */ FMT("1100101000000000", "zac"), /* CA00 */ FMT("1100101000000001", "lack 01h"), /* CAxx */ FMT("1100101000000010", "lack 02h"), FMT("1100101000000011", "lack 03h"), FMT("1100101000000100", "lack 04h"), FMT("1100101000000101", "lack 05h"), FMT("1100101000000110", "lack 06h"), FMT("1100101000000111", "lack 07h"), FMT("1100101000001000", "lack 08h"), FMT("1100101000001001", "lack 09h"), FMT("1100101000001010", "lack 0Ah"), FMT("1100101000001011", "lack 0Bh"), FMT("1100101000001100", "lack 0Ch"), FMT("1100101000001101", "lack 0Dh"), FMT("1100101000001110", "lack 0Eh"), FMT("1100101000001111", "lack 0Fh"), FMT("110010100001tttt", "lack 1%T"), FMT("110010100010tttt", "lack 2%T"), FMT("110010100011tttt", "lack 3%T"), FMT("110010100100tttt", "lack 4%T"), FMT("110010100101tttt", "lack 5%T"), FMT("110010100110tttt", "lack 6%T"), FMT("110010100111tttt", "lack 7%T"), FMT("110010101000tttt", "lack 8%T"), FMT("110010101001tttt", "lack 9%T"), FMT("110010101010tttt", "lack A%T"), FMT("110010101011tttt", "lack B%T"), FMT("110010101100tttt", "lack C%T"), FMT("110010101101tttt", "lack D%T"), FMT("110010101110tttt", "lack E%T"), FMT("110010101111tttt", "lack F%T"), FMT("11001011dddddddd", "rptk %D"), /* CBxx */ FMT("11001100dddddddd", "addk %D"), /* CCxx */ FMT("11001101dddddddd", "subk %D"), /* CDxx */ FMT("1100111000000000", "eint"), /* CE00 */ FMT("1100111000000001", "dint"), /* CE01 */ FMT("1100111000000010", "rovm"), /* CE02 */ FMT("1100111000000011", "sovm"), /* CE03 */ FMT("1100111000000100", "cnfd"), /* CE04 */ FMT("1100111000000101", "cnfp"), /* CE05 */ FMT("1100111000000110", "rsxm"), /* CE06 */ FMT("1100111000000111", "ssxm"), /* CE07 */ FMT("11001110000010kk", "spm %K"), /* CE0x */ FMT("1100111000001100", "rxf"), /* CE0C */ FMT("1100111000001101", "sxf"), /* CE0D */ FMT("110011100000111k", "fort %K"), /* CE0x */ FMT("1100111000010100", "pac"), /* CE14 */ FMT("1100111000010101", "apac"), /* CE15 */ FMT("1100111000010110", "spac"), /* CE16 */ FMT("1100111000011000", "sfl"), /* CE18 */ FMT("1100111000011001", "sfr"), /* CE19 */ FMT("1100111000011011", "abs"), /* CE1B */ FMT("1100111000011100", "push"), /* CE1C */ FMT("1100111000011101", "pop"), /* CE1D */ FMT("1100111000011110", "trap"), /* CE1E */ FMT("1100111000011111", "idle"), /* CE1F */ FMT("1100111000100000", "rtxm"), /* CE20 */ FMT("1100111000100001", "stxm"), /* CE21 */ FMT("1100111000100011", "neg"), /* CE23 */ FMT("1100111000100100", "cala"), /* CE24 */ FMT("1100111000100101", "bacc"), /* CE25 */ FMT("1100111000100110", "ret"), /* CE26 */ FMT("1100111000100111", "cmpl"), /* CE27 */ FMT("1100111000110000", "rc"), /* CE30 */ FMT("1100111000110001", "sc"), /* CE31 */ FMT("1100111000110010", "rtc"), /* CE32 */ FMT("1100111000110011", "stc"), /* CE33 */ FMT("1100111000110100", "rol"), /* CE34 */ FMT("1100111000110101", "ror"), /* CE35 */ FMT("1100111000110110", "rfsm"), /* CE36 */ FMT("1100111000110111", "sfsm"), /* CE37 */ FMT("1100111000111000", "rhm"), /* CE38 */ FMT("1100111000111001", "shm"), /* CE39 */ FMT("11001110001111kk", "conf %K"), /* CE3x */ FMT("11001110010100cc", "cmpr %C"), /* CE5x */ FMT("110011101mmm0010", "norm %M"), /* CEx2 */ FMT("110011110aaaaaaa", "mpys %A"), /* CFxx */ FMT("110011111mmmnnnn", "mpys %M%N"), FMT("11010rrr00000000wwwwwwwwwwwwwwww", "lrlk %R,%W"), /* Dx00 */ FMT("1101tttt00000001wwwwwwwwwwwwwwww", "lalk %W,%T"), /* Dx01 */ FMT("1101tttt00000010wwwwwwwwwwwwwwww", "adlk %W,%T"), /* Dx02 */ FMT("1101tttt00000011wwwwwwwwwwwwwwww", "sblk %W,%T"), /* Dx03 */ FMT("1101tttt00000100wwwwwwwwwwwwwwww", "andk %W,%T"), /* Dx04 */ FMT("1101tttt00000101wwwwwwwwwwwwwwww", "ork %W,%T"), /* Dx05 */ FMT("1101tttt00000110wwwwwwwwwwwwwwww", "xork %W,%T"), /* Dx06 */ FMT("1110pppp0aaaaaaa", "out %A,%P"), /* Exxx */ FMT("1110pppp1mmmnnnn", "out %M,%P%N"), FMT("111100001mmmnnnnbbbbbbbbbbbbbbbb", "bv %B %M%N"), /* F0xx */ FMT("111100011mmmnnnnbbbbbbbbbbbbbbbb", "bgz %B %M%N"), /* F1xx */ FMT("111100101mmmnnnnbbbbbbbbbbbbbbbb", "blez %B %M%N"), /* F2xx */ FMT("111100111mmmnnnnbbbbbbbbbbbbbbbb", "blz %B %M%N"), /* F3xx */ FMT("111101001mmmnnnnbbbbbbbbbbbbbbbb", "bgez %B %M%N"), /* F4xx */ FMT("111101011mmmnnnnbbbbbbbbbbbbbbbb", "bnz %B %M%N"), /* F5xx */ FMT("111101101mmmnnnnbbbbbbbbbbbbbbbb", "bz %B %M%N"), /* F6xx */ FMT("111101111mmmnnnnbbbbbbbbbbbbbbbb", "bnv %B %M%N"), /* F7xx */ FMT("111110001mmmnnnnbbbbbbbbbbbbbbbb", "bbz %B %M%N"), /* F8xx */ FMT("111110011mmmnnnnbbbbbbbbbbbbbbbb", "bbnz %B %M%N"), /* F9xx */ FMT("111110101mmmnnnnbbbbbbbbbbbbbbbb", "bioz %B %M%N"), /* FAxx */ FMT("111110111mmmnnnnbbbbbbbbbbbbbbbb", "banz %B %M%N"), /* FBxx */ FMT("111111000aaaaaaabbbbbbbbbbbbbbbb", "blkp %B,%A"), /* FCxx */ FMT("111111001mmmnnnnbbbbbbbbbbbbbbbb", "blkp %B,%M%N"), FMT("111111010aaaaaaabbbbbbbbbbbbbbbb", "blkd %B,%A"), /* FDxx */ FMT("111111011mmmnnnnbbbbbbbbbbbbbbbb", "blkd %B,%M%N"), FMT("111111101mmmnnnnbbbbbbbbbbbbbbbb", "call %B %M%N"), /* FExx */ FMT("111111111mmmnnnnbbbbbbbbbbbbbbbb", "b %B %M%N"), /* FFxx */ NULL }; #define MAX_OPS (((sizeof(TMS32025Formats) / sizeof(TMS32025Formats[0])) - 1) / PTRS_PER_FORMAT) typedef struct opcode { word mask; /* instruction mask */ word bits; /* constant bits */ word extcode; /* value that gets extension code */ const char *parse; /* how to parse bits */ const char *fmt; /* instruction format */ } TMS32025Opcode; static TMS32025Opcode Op[MAX_OPS+1]; static int OpInizialized = 0; static void InitDasm32025(void) { const char *p, **ops; word mask, bits; int bit; int i; ops = TMS32025Formats; i = 0; while (*ops) { p = *ops; mask = 0; bits = 0; bit = 15; while (*p && bit >= 0) { switch (*p++) { case '1': mask |= 1<= 0) { /* mame_printf_debug("{%c/%d}",*cp,bit); */ switch(*cp) { case 'a': a <<=1; a |= ((code & (1<