diff options
Diffstat (limited to 'src/emu/cpu/pps4/pps4dasm.c')
-rw-r--r-- | src/emu/cpu/pps4/pps4dasm.c | 529 |
1 files changed, 410 insertions, 119 deletions
diff --git a/src/emu/cpu/pps4/pps4dasm.c b/src/emu/cpu/pps4/pps4dasm.c index f3cb664f0e9..35eda8e09fb 100644 --- a/src/emu/cpu/pps4/pps4dasm.c +++ b/src/emu/cpu/pps4/pps4dasm.c @@ -1,135 +1,426 @@ // license:BSD-3-Clause -// copyright-holders:Miodrag Milanovic +// copyright-holders:Juergen Buchmueller <pullmoll@t-online.de> /***************************************************************************** * * pps4dasm.c * * Rockwell PPS-4 CPU Disassembly * + * + * TODO: double verify all opcodes with t_Ixx flags + * *****************************************************************************/ - #include "emu.h" #define OP(A) oprom[(A) - PC] #define ARG(A) opram[(A) - PC] +typedef enum pps4_token_e { + t_AD, t_ADC, t_ADSK, t_ADCSK, t_ADI, + t_DC, t_AND, t_OR, t_EOR, t_COMP, + t_SC, t_RC, t_SF1, t_RF1, t_SF2, + t_RF2, t_LD, t_EX, t_EXD, t_LDI, + t_LAX, t_LXA, t_LABL, t_LBMX, t_LBUA, + t_XABL, t_XBMX, t_XAX, t_XS, t_CYS, + t_LB, t_LBL, t_INCB, t_DECB, t_T, + t_TM, t_TL, t_TML, t_SKC, t_SKZ, + t_SKBI, t_SKF1, t_SKF2, t_RTN, t_RTNSK, + t_IOL, t_DIA, t_DIB, t_DOA, t_SAG, + t_COUNT, + t_MASK = (1 << 6) - 1, + t_I3c = 1 << 6, /* immediate 3 bit constant, complemented */ + t_I4 = 1 << 7, /* immediate 4 bit constant */ + t_I4c = 1 << 8, /* immediate 4 bit constant, complemented */ + t_I4p = 1 << 9, /* immediate 4 bit offset into page 3 */ + t_I6p = 1 << 10, /* immediate 6 bit constant; address in current page */ + t_I8 = 1 << 11, /* immediate 8 bit constant (I/O port number) */ + t_I8c = 1 << 12, /* immediate 8 bit constant inverted */ +} pps4_token_e; + +static const char *token_str[t_COUNT] = { + "ad", /* add */ + "adc", /* add with carry-in */ + "adsk", /* add and skip on carry-out */ + "adcsk", /* add with carry-in and skip on carry-out */ + "adi", /* add immediate */ + "dc", /* decimal correction */ + "and", /* logical and */ + "or", /* logical or */ + "eor", /* logical exclusive-orf */ + "comp", /* complement */ + "sc", /* set C flip-flop */ + "rc", /* reset C flip-flop */ + "sf1", /* set FF1 flip-flop */ + "rf1", /* reset FF1 flip-flop */ + "sf2", /* set FF2 flip-flop */ + "rf2", /* reset FF2 flip-flop */ + "ld", /* load accumulator from memory */ + "ex", /* exchange accumulator and memory */ + "exd", /* exchange accumulator and memory and decrement BL */ + "ldi", /* load accumulator immediate */ + "lax", /* load accumulator from X register */ + "lxa", /* load X register from accumulator */ + "labl", /* load accumulator with BL */ + "lbmx", /* load BM with X */ + "lbua", /* load BU with A */ + "xabl", /* exchange accumulator and BL */ + "xbmx", /* exchange BM and X */ + "xax", /* exchange accumulator and X */ + "xs", /* exchange SA and SB */ + "cys", /* cycle SA register and accumulator */ + "lb", /* load B indirect */ + "lbl", /* load B long */ + "incb", /* increment BL */ + "decb", /* decrement BL */ + "t", /* transfer */ + "tm", /* transfer and mark indirect */ + "tl", /* transfer long */ + "tml", /* transfer and mark long */ + "skc", /* skip on C flip-flop equals 1 */ + "skz", /* skip on accumulator zero */ + "skbi", /* skip on BL equal to immediate */ + "skf1", /* skip on FF1 flip-flop equals 1 */ + "skf2", /* skip on FF2 flip-flop equals 1 */ + "rtn", /* return */ + "rtnsk", /* return and skip */ + "iol", /* input/output long */ + "dia", /* discrete input group A */ + "dib", /* discrete input group B */ + "doa", /* discrete output */ + "sag" /* special address generation */ +}; + +static const UINT16 table[] = { + t_LBL | t_I8c, /* 00 */ + t_TML | t_I4 | t_I8, /* 01 */ + t_TML | t_I4 | t_I8, /* 02 */ + t_TML | t_I4 | t_I8, /* 03 */ + t_LBUA, /* 04 */ + t_RTN, /* 05 */ + t_XS, /* 06 */ + t_RTNSK, /* 07 */ + t_ADCSK, /* 08 */ + t_ADSK, /* 09 */ + t_ADC, /* 0a */ + t_AD, /* 0b */ + t_EOR, /* 0c */ + t_AND, /* 0d */ + t_COMP, /* 0e */ + t_OR, /* 0f */ + + t_LBMX, /* 10 */ + t_LABL, /* 11 */ + t_LAX, /* 12 */ + t_SAG, /* 13 */ + t_SKF2, /* 14 */ + t_SKC, /* 15 */ + t_SKF1, /* 16 */ + t_INCB, /* 17 */ + t_XBMX, /* 18 */ + t_XABL, /* 19 */ + t_XAX, /* 1a */ + t_LXA, /* 1b */ + t_IOL | t_I8, /* 1c */ + t_DOA, /* 1d */ + t_SKZ, /* 1e */ + t_DECB, /* 1f */ + + t_SC, /* 20 */ + t_SF2, /* 21 */ + t_SF1, /* 22 */ + t_DIB, /* 23 */ + t_RC, /* 24 */ + t_RF2, /* 25 */ + t_RF1, /* 26 */ + t_DIA, /* 27 */ + t_EXD | t_I3c, /* 28 */ + t_EXD | t_I3c, /* 29 */ + t_EXD | t_I3c, /* 2a */ + t_EXD | t_I3c, /* 2b */ + t_EXD | t_I3c, /* 2c */ + t_EXD | t_I3c, /* 2d */ + t_EXD | t_I3c, /* 2e */ + t_EXD | t_I3c, /* 2f */ + + t_LD | t_I3c, /* 30 */ + t_LD | t_I3c, /* 31 */ + t_LD | t_I3c, /* 32 */ + t_LD | t_I3c, /* 33 */ + t_LD | t_I3c, /* 34 */ + t_LD | t_I3c, /* 35 */ + t_LD | t_I3c, /* 36 */ + t_LD | t_I3c, /* 37 */ + t_EX | t_I3c, /* 38 */ + t_EX | t_I3c, /* 39 */ + t_EX | t_I3c, /* 3a */ + t_EX | t_I3c, /* 3b */ + t_EX | t_I3c, /* 3c */ + t_EX | t_I3c, /* 3d */ + t_EX | t_I3c, /* 3e */ + t_EX | t_I3c, /* 3f */ + + t_SKBI | t_I4, /* 40 */ + t_SKBI | t_I4, /* 41 */ + t_SKBI | t_I4, /* 42 */ + t_SKBI | t_I4, /* 43 */ + t_SKBI | t_I4, /* 44 */ + t_SKBI | t_I4, /* 45 */ + t_SKBI | t_I4, /* 46 */ + t_SKBI | t_I4, /* 47 */ + t_SKBI | t_I4, /* 48 */ + t_SKBI | t_I4, /* 49 */ + t_SKBI | t_I4, /* 4a */ + t_SKBI | t_I4, /* 4b */ + t_SKBI | t_I4, /* 4c */ + t_SKBI | t_I4, /* 4d */ + t_SKBI | t_I4, /* 4e */ + t_SKBI | t_I4, /* 4f */ + + t_TL | t_I4 | t_I8, /* 50 */ + t_TL | t_I4 | t_I8, /* 51 */ + t_TL | t_I4 | t_I8, /* 52 */ + t_TL | t_I4 | t_I8, /* 53 */ + t_TL | t_I4 | t_I8, /* 54 */ + t_TL | t_I4 | t_I8, /* 55 */ + t_TL | t_I4 | t_I8, /* 56 */ + t_TL | t_I4 | t_I8, /* 57 */ + t_TL | t_I4 | t_I8, /* 58 */ + t_TL | t_I4 | t_I8, /* 59 */ + t_TL | t_I4 | t_I8, /* 5a */ + t_TL | t_I4 | t_I8, /* 5b */ + t_TL | t_I4 | t_I8, /* 5c */ + t_TL | t_I4 | t_I8, /* 5d */ + t_TL | t_I4 | t_I8, /* 5e */ + t_TL | t_I4 | t_I8, /* 5f */ + + t_ADI | t_I4c, /* 60 */ + t_ADI | t_I4c, /* 61 */ + t_ADI | t_I4c, /* 62 */ + t_ADI | t_I4c, /* 63 */ + t_ADI | t_I4c, /* 64 */ + t_DC, /* 65 */ + t_ADI | t_I4c, /* 66 */ + t_ADI | t_I4c, /* 67 */ + t_ADI | t_I4c, /* 68 */ + t_ADI | t_I4c, /* 69 */ + t_ADI | t_I4c, /* 6a */ + t_ADI | t_I4c, /* 6b */ + t_ADI | t_I4c, /* 6c */ + t_ADI | t_I4c, /* 6d */ + t_ADI | t_I4c, /* 6e */ + t_CYS, /* 6f */ + + t_LDI | t_I4c, /* 70 */ + t_LDI | t_I4c, /* 71 */ + t_LDI | t_I4c, /* 72 */ + t_LDI | t_I4c, /* 73 */ + t_LDI | t_I4c, /* 74 */ + t_LDI | t_I4c, /* 75 */ + t_LDI | t_I4c, /* 76 */ + t_LDI | t_I4c, /* 77 */ + t_LDI | t_I4c, /* 78 */ + t_LDI | t_I4c, /* 79 */ + t_LDI | t_I4c, /* 7a */ + t_LDI | t_I4c, /* 7b */ + t_LDI | t_I4c, /* 7c */ + t_LDI | t_I4c, /* 7d */ + t_LDI | t_I4c, /* 7e */ + t_LDI | t_I4c, /* 7f */ + + t_T | t_I6p, /* 80 */ + t_T | t_I6p, /* 81 */ + t_T | t_I6p, /* 82 */ + t_T | t_I6p, /* 83 */ + t_T | t_I6p, /* 84 */ + t_T | t_I6p, /* 85 */ + t_T | t_I6p, /* 86 */ + t_T | t_I6p, /* 87 */ + t_T | t_I6p, /* 88 */ + t_T | t_I6p, /* 89 */ + t_T | t_I6p, /* 8a */ + t_T | t_I6p, /* 8b */ + t_T | t_I6p, /* 8c */ + t_T | t_I6p, /* 8d */ + t_T | t_I6p, /* 8e */ + t_T | t_I6p, /* 8f */ + + t_T | t_I6p, /* 90 */ + t_T | t_I6p, /* 91 */ + t_T | t_I6p, /* 92 */ + t_T | t_I6p, /* 93 */ + t_T | t_I6p, /* 94 */ + t_T | t_I6p, /* 95 */ + t_T | t_I6p, /* 96 */ + t_T | t_I6p, /* 97 */ + t_T | t_I6p, /* 98 */ + t_T | t_I6p, /* 99 */ + t_T | t_I6p, /* 9a */ + t_T | t_I6p, /* 9b */ + t_T | t_I6p, /* 9c */ + t_T | t_I6p, /* 9d */ + t_T | t_I6p, /* 9e */ + t_T | t_I6p, /* 9f */ + + t_T | t_I6p, /* a0 */ + t_T | t_I6p, /* a1 */ + t_T | t_I6p, /* a2 */ + t_T | t_I6p, /* a3 */ + t_T | t_I6p, /* a4 */ + t_T | t_I6p, /* a5 */ + t_T | t_I6p, /* a6 */ + t_T | t_I6p, /* a7 */ + t_T | t_I6p, /* a8 */ + t_T | t_I6p, /* a9 */ + t_T | t_I6p, /* aa */ + t_T | t_I6p, /* ab */ + t_T | t_I6p, /* ac */ + t_T | t_I6p, /* ad */ + t_T | t_I6p, /* ae */ + t_T | t_I6p, /* af */ + + t_T | t_I6p, /* b0 */ + t_T | t_I6p, /* b1 */ + t_T | t_I6p, /* b2 */ + t_T | t_I6p, /* b3 */ + t_T | t_I6p, /* b4 */ + t_T | t_I6p, /* b5 */ + t_T | t_I6p, /* b6 */ + t_T | t_I6p, /* b7 */ + t_T | t_I6p, /* b8 */ + t_T | t_I6p, /* b9 */ + t_T | t_I6p, /* ba */ + t_T | t_I6p, /* bb */ + t_T | t_I6p, /* bc */ + t_T | t_I6p, /* bd */ + t_T | t_I6p, /* be */ + t_T | t_I6p, /* bf */ + + t_LB | t_I4p, /* c0 */ + t_LB | t_I4p, /* c1 */ + t_LB | t_I4p, /* c2 */ + t_LB | t_I4p, /* c3 */ + t_LB | t_I4p, /* c4 */ + t_LB | t_I4p, /* c5 */ + t_LB | t_I4p, /* c6 */ + t_LB | t_I4p, /* c7 */ + t_LB | t_I4p, /* c8 */ + t_LB | t_I4p, /* c9 */ + t_LB | t_I4p, /* ca */ + t_LB | t_I4p, /* cb */ + t_LB | t_I4p, /* cc */ + t_LB | t_I4p, /* cd */ + t_LB | t_I4p, /* ce */ + t_LB | t_I4p, /* cf */ + + t_TM | t_I6p, /* d0 */ + t_TM | t_I6p, /* d1 */ + t_TM | t_I6p, /* d2 */ + t_TM | t_I6p, /* d3 */ + t_TM | t_I6p, /* d4 */ + t_TM | t_I6p, /* d5 */ + t_TM | t_I6p, /* d6 */ + t_TM | t_I6p, /* d7 */ + t_TM | t_I6p, /* d8 */ + t_TM | t_I6p, /* d9 */ + t_TM | t_I6p, /* da */ + t_TM | t_I6p, /* db */ + t_TM | t_I6p, /* dc */ + t_TM | t_I6p, /* dd */ + t_TM | t_I6p, /* de */ + t_TM | t_I6p, /* df */ + + t_TM | t_I6p, /* e0 */ + t_TM | t_I6p, /* e1 */ + t_TM | t_I6p, /* e2 */ + t_TM | t_I6p, /* e3 */ + t_TM | t_I6p, /* e4 */ + t_TM | t_I6p, /* e5 */ + t_TM | t_I6p, /* e6 */ + t_TM | t_I6p, /* e7 */ + t_TM | t_I6p, /* e8 */ + t_TM | t_I6p, /* e9 */ + t_TM | t_I6p, /* ea */ + t_TM | t_I6p, /* eb */ + t_TM | t_I6p, /* ec */ + t_TM | t_I6p, /* ed */ + t_TM | t_I6p, /* ee */ + t_TM | t_I6p, /* ef */ + + t_TM | t_I6p, /* f0 */ + t_TM | t_I6p, /* f1 */ + t_TM | t_I6p, /* f2 */ + t_TM | t_I6p, /* f3 */ + t_TM | t_I6p, /* f4 */ + t_TM | t_I6p, /* f5 */ + t_TM | t_I6p, /* f6 */ + t_TM | t_I6p, /* f7 */ + t_TM | t_I6p, /* f8 */ + t_TM | t_I6p, /* f9 */ + t_TM | t_I6p, /* fa */ + t_TM | t_I6p, /* fb */ + t_TM | t_I6p, /* fc */ + t_TM | t_I6p, /* fd */ + t_TM | t_I6p, /* fe */ + t_TM | t_I6p, /* ff */ +}; + CPU_DISASSEMBLE( pps4 ) { - UINT32 flags = 0; - unsigned PC = pc; - UINT8 op; - switch (op = OP(pc++)) - { - // Arithmetic instructions - case 0x0b: sprintf (buffer,"ad"); break; - case 0x0a: sprintf (buffer,"adc"); break; - case 0x09: sprintf (buffer,"adsk"); break; - case 0x08: sprintf (buffer,"adcsk"); break; - case 0x60: case 0x61: case 0x62: case 0x63: - case 0x64: case 0x66: case 0x67: case 0x68: - case 0x69: case 0x6a: case 0x6b: case 0x6c: - case 0x6d: case 0x6e: - sprintf (buffer,"adi %01x",(op & 0x0f)); break; - case 0x65: sprintf (buffer,"dc"); break; - // Logical instructions - case 0x0d: sprintf (buffer,"and"); break; - case 0x0f: sprintf (buffer,"or"); break; - case 0x0c: sprintf (buffer,"eor"); break; - case 0x0e: sprintf (buffer,"comp"); break; - // Data transfer instructions - case 0x20: sprintf (buffer,"sc"); break; - case 0x24: sprintf (buffer,"rc"); break; - case 0x22: sprintf (buffer,"sf1"); break; - case 0x26: sprintf (buffer,"rf1"); break; - case 0x21: sprintf (buffer,"sf2"); break; - case 0x25: sprintf (buffer,"rf2"); break; - case 0x30: case 0x31: case 0x32: case 0x33: - case 0x34: case 0x35: case 0x36: case 0x37: - sprintf (buffer,"ld %01x",(op & 0x07)); break; - case 0x38: case 0x39: case 0x3a: case 0x3b: - case 0x3c: case 0x3d: case 0x3e: case 0x3f: - sprintf (buffer,"ex %01x",(op & 0x07)); break; - case 0x28: case 0x29: case 0x2a: case 0x2b: - case 0x2c: case 0x2d: case 0x2e: case 0x2f: - sprintf (buffer,"exd %01x",(op & 0x07)); break; - case 0x70: case 0x71: case 0x72: case 0x73: - case 0x74: case 0x75: case 0x76: case 0x77: - sprintf (buffer,"ldi %01x",(op & 0x0f)); break; - case 0x12: sprintf (buffer,"lax"); break; - case 0x1b: sprintf (buffer,"lxa"); break; - case 0x11: sprintf (buffer,"labl"); break; - case 0x10: sprintf (buffer,"lbmx"); break; - case 0x04: sprintf (buffer,"lbua"); break; - case 0x19: sprintf (buffer,"xabl"); break; - case 0x18: sprintf (buffer,"xbmx"); break; - case 0x1a: sprintf (buffer,"xax"); break; - case 0x06: sprintf (buffer,"xs"); break; - case 0x6f: sprintf (buffer,"cys"); break; - case 0xc0: case 0xc1: case 0xc2: case 0xc3: - case 0xc4: case 0xc5: case 0xc6: case 0xc7: - case 0xc8: case 0xc9: case 0xca: case 0xcb: - case 0xcc: case 0xcd: case 0xce: case 0xcf: - sprintf (buffer,"lb %02x",ARG(pc)); pc++; break; - case 0x00: sprintf (buffer,"lbl %02x",ARG(pc)); pc++; break; - case 0x17: sprintf (buffer,"incb"); break; - case 0x1f: sprintf (buffer,"decb"); break; - // Control transfer instructions - case 0x80: case 0x81: case 0x82: case 0x83: - case 0x84: case 0x85: case 0x86: case 0x87: - case 0x88: case 0x89: case 0x8a: case 0x8b: - case 0x8c: case 0x8d: case 0x8e: case 0x8f: - case 0x90: case 0x91: case 0x92: case 0x93: - case 0x94: case 0x95: case 0x96: case 0x97: - case 0x98: case 0x99: case 0x9a: case 0x9b: - case 0x9c: case 0x9d: case 0x9e: case 0x9f: - case 0xa0: case 0xa1: case 0xa2: case 0xa3: - case 0xa4: case 0xa5: case 0xa6: case 0xa7: - case 0xa8: case 0xa9: case 0xaa: case 0xab: - case 0xac: case 0xad: case 0xae: case 0xaf: - case 0xb0: case 0xb1: case 0xb2: case 0xb3: - case 0xb4: case 0xb5: case 0xb6: case 0xb7: - case 0xb8: case 0xb9: case 0xba: case 0xbb: - case 0xbc: case 0xbd: case 0xbe: case 0xbf: - sprintf (buffer,"t %02x",(op & 0x3f)); break; - case 0xd0: case 0xd1: case 0xd2: case 0xd3: - case 0xd4: case 0xd5: case 0xd6: case 0xd7: - case 0xd8: case 0xd9: case 0xda: case 0xdb: - case 0xdc: case 0xdd: case 0xde: case 0xdf: - case 0xe0: case 0xe1: case 0xe2: case 0xe3: - case 0xe4: case 0xe5: case 0xe6: case 0xe7: - case 0xe8: case 0xe9: case 0xea: case 0xeb: - case 0xec: case 0xed: case 0xee: case 0xef: - case 0xf0: case 0xf1: case 0xf2: case 0xf3: - case 0xf4: case 0xf5: case 0xf6: case 0xf7: - case 0xf8: case 0xf9: case 0xfa: case 0xfb: - case 0xfc: case 0xfd: case 0xfe: case 0xff: - sprintf (buffer,"tm %02x %02x",(op & 0x3f),ARG(pc)); pc++; break; - case 0x50: case 0x51: case 0x52: case 0x53: - case 0x54: case 0x55: case 0x56: case 0x57: - case 0x58: case 0x59: case 0x5a: case 0x5b: - case 0x5c: case 0x5d: case 0x5e: case 0x5f: - sprintf (buffer,"tl %01x %02x",(op & 0x0f),ARG(pc)); pc++; break; - case 0x01: case 0x02: case 0x03: - sprintf (buffer,"tml %02x",ARG(pc)); pc++; break; - case 0x15: sprintf (buffer,"skc"); break; - case 0x1e: sprintf (buffer,"skz"); break; - case 0x40: case 0x41: case 0x42: case 0x43: - case 0x44: case 0x45: case 0x46: case 0x47: - case 0x48: case 0x49: case 0x4a: case 0x4b: - case 0x4c: case 0x4d: case 0x4e: case 0x4f: - sprintf (buffer,"skbi %01x",(op & 0x0f)); break; - case 0x16: sprintf (buffer,"skf1"); break; - case 0x14: sprintf (buffer,"skf2"); break; - case 0x05: sprintf (buffer,"rtn"); break; - case 0x07: sprintf (buffer,"rtnsk"); break; - // Input/Output instructions - case 0x1c: sprintf (buffer,"iol %02x",ARG(pc)); pc++; break; - case 0x27: sprintf (buffer,"dia"); break; - case 0x23: sprintf (buffer,"dib"); break; - case 0x1d: sprintf (buffer,"doa"); break; - // Special instructions - case 0x13: sprintf (buffer,"sag"); break; - } - - return (pc - PC) | flags | DASMFLAG_SUPPORTED; + UINT32 flags = 0; + unsigned PC = pc; + UINT8 op = OP(pc++); + UINT32 tok = table[op]; + char *dst = 0; + + if (0 == (tok & t_MASK)) + sprintf(buffer, "%s", token_str[tok & t_MASK]); + else + dst = buffer + sprintf(buffer, "%-7s", token_str[tok & t_MASK]); + + if (tok & t_I3c) { + // 3 bit immediate, complemented + UINT8 i = ~op & 7; + dst += sprintf(dst, "%x", i); + } + + if (tok & t_I4) { + // 4 bit immediate + UINT8 i = op & 15; + dst += sprintf(dst, "%x", i); + } + + if (tok & t_I4c) { + // 4 bit immediate, complemented + UINT8 i = ~op & 15; + dst += sprintf(dst, "%x", i); + } + + if (tok & t_I4p) { + // 4 bit immediate offset into page 3 + UINT8 i = op & 15; + dst += sprintf(dst, "[%x]", 0x0c0 | i); + } + + if (tok & t_I6p) { + // 6 bit immediate offset into current page + UINT8 i = op & 63; + dst += sprintf(dst, "%x", (PC & ~63) | i); + } + + if (tok & t_I8) { + // 8 bit immediate I/O port address + UINT8 arg = ARG(pc++); + dst += sprintf(dst, "%02x", arg); + } + + if (tok & t_I8c) { + // 8 bit immediate offset into page + UINT16 arg = ~ARG(pc++) & 255; + dst += sprintf(dst, "%03x", arg); + } + + if (0x05 == op || 0x07 == op) // RTN or RTNSK + flags |= DASMFLAG_STEP_OUT; + + return (pc - PC) | flags | DASMFLAG_SUPPORTED; } |