From 704e81105dda7c75c85551b641b2a6ede8facb24 Mon Sep 17 00:00:00 2001 From: Ariane Fugmann Date: Mon, 4 May 2020 14:04:11 +0200 Subject: [PATCH] i960dasm: rewrote disassembler [SailorSat] --- src/devices/cpu/i960/i960dis.cpp | 758 ++++++++++++++++++++----------- src/devices/cpu/i960/i960dis.h | 12 +- 2 files changed, 499 insertions(+), 271 deletions(-) diff --git a/src/devices/cpu/i960/i960dis.cpp b/src/devices/cpu/i960/i960dis.cpp index eb6227a8154..5bb99c75458 100644 --- a/src/devices/cpu/i960/i960dis.cpp +++ b/src/devices/cpu/i960/i960dis.cpp @@ -9,90 +9,169 @@ #include "emu.h" #include "i960dis.h" +/* + Based on documents: + 270567-001 80960KB Programmer's Reference Manual (March 1988) + 270710-003 i960 CA/CF Microprocessor User's Manual (March 1994) + 271081-001 80960MC Programmer's Reference Manual (July 1988) + 272483-001 i960 Jx Microprocessor User's Manual (September 1994) + 272484-002 i960 Hx Microprocessor Developer's Manual (September 1998) + 272736-002 i960 Rx I/O Microprocessor Developer's Manual (April 1997) + 273353-001 Intel 80303 I/O Processor Developer's Manual (May 2000) +*/ const i960_disassembler::mnemonic_t i960_disassembler::mnemonic[256] = { - { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, // 00 - { "b", 8 }, { "call", 8 }, { "ret", 9 }, { "bal", 8 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, + { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, // 00 + { "b", 1, 1 }, { "call", 1, 1 }, { "ret", 1, 0 }, { "bal", 1, 1 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, - { "bno", 8 }, { "bg", 8 }, { "be", 8 }, { "bge", 8 }, { "bl", 8 }, { "bne", 8 }, { "ble", 8 }, { "bo", 8 }, // 10 - { "faultno", 0 }, { "faultg", 0 }, { "faulte", 0 }, { "faultge", 0 }, { "faultl", 0 }, { "faultne", 0 }, { "faultle", 0 }, { "faulto", 0 }, + { "bno", 1, 1 }, { "bg", 1, 1 }, { "be", 1, 1 }, { "bge", 1, 1 }, { "bl", 1, 1 }, { "bne", 1, 1 }, { "ble", 1, 1 }, { "bo", 1, 1 }, // 10 + { "faultno", 1, 0 }, { "faultg", 1, 0 }, { "faulte", 1, 0 }, { "faultge", 1, 0 }, { "faultl", 1, 0 }, { "faultne", 1, 0 }, { "faultle", 1, 0 }, { "faulto", 1, 0 }, - { "testno", 10 }, { "testg", 10 }, { "teste", 10 }, { "testge", 10 }, { "testl", 10 }, { "testne", 10 }, { "testle", 10 }, { "testo", 10 }, // 20 - { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, + { "testno", 2, 1 }, { "testg", 2, 1 }, { "teste", 2, 1 }, { "testge", 2, 1 }, { "testl", 2, 1 }, { "testne", 2, 1 }, { "testle", 2, 1 }, { "testo", 2, 1 }, // 20 + { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, - { "bbc", 6 }, { "cmpobg", 7 }, { "cmpobe", 7 }, { "cmpobge", 7 }, { "cmpobl", 7 }, { "cmpobne", 7 }, { "cmpoble", 7 }, { "bbs", 6 }, // 30 - { "cmpibno", 7 }, { "cmpibg", 7 }, { "cmpibe", 7 }, { "cmpibge", 7 }, { "cmpibl", 7 }, { "cmpibne", 7 }, { "cmpible", 7 }, { "cmpibo", 7 }, + { "bbc", 2, 3 }, { "cmpobg", 2, 3 }, { "cmpobe", 2, 3 }, { "cmpobge", 2, 3 }, { "cmpobl", 2, 3 }, { "cmpobne", 2, 3 }, { "cmpoble", 2, 3 }, { "bbs", 2, 3 }, // 30 + { "cmpibno", 2, 3 }, { "cmpibg", 2, 3 }, { "cmpibe", 2, 3 }, { "cmpibge", 2, 3 }, { "cmpibl", 2, 3 }, { "cmpibne", 2, 3 }, { "cmpible", 2, 3 }, { "cmpibo", 2, 3 }, - { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, // 40 - { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, + { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, // 40 + { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, - { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, // 50 - { "58", 3 }, { "59", 3 }, { "5A", 3 }, { "5B", 3 }, { "5C", 2 }, { "5D", 2 }, { "?", 0 }, { "5F", 2 }, + { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, // 50 + { "58", 4, 0 }, { "59", 4, 0 }, { "5A", 4, 0 }, { "5B", 4, 0 }, { "5C", 4, 0 }, { "5D", 4, 0 }, { "?", 0, 0 }, { "5F", 4, 0 }, - { "60", 3 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "64", 3 }, { "65", 3 }, { "calls", 0 }, { "67", 3 }, // 60 - { "68", 3 }, { "69", 3 }, { "?", 0 }, { "?", 0 }, { "6C", 3 }, { "6D", 3 }, { "6E", 3 }, { "?", 0 }, + { "60", 4, 0 }, { "61", 4, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "64", 4, 0 }, { "65", 4, 0 }, { "66", 4, 0 }, { "67", 4, 0 }, // 60 + { "68", 4, 0 }, { "69", 4, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "6C", 4, 0 }, { "6D", 4, 0 }, { "6E", 4, 0 }, { "?", 0, 0 }, - { "70", 3 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "74", 3 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, // 70 - { "78", 3 }, { "79", 3 }, { "7A", 3 }, { "7B", 3 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, + { "70", 4, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "74", 4, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, // 70 + { "78", 4, 0 }, { "79", 4, 0 }, { "7A", 4, 0 }, { "7B", 4, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, - { "ldob", 4 }, { "?", 0 }, { "stob", 1 }, { "?", 0 }, { "bx", 11 }, { "balx", 1 }, { "callx", 11 }, { "?", 0 }, // 80 - { "ldos", 4 }, { "?", 0 }, { "stos", 1 }, { "?", 0 }, { "lda", 4 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, + { "ldob", 3, 2 }, { "?", 0, 0 }, { "stob", 3, -2 }, { "?", 0, 0 }, { "bx", 3, 1 }, { "balx", 3, 2 }, { "callx", 3, 1 }, { "?", 0, 0 }, // 80 + { "ldos", 3, 2 }, { "?", 0, 0 }, { "stos", 3, -2 }, { "?", 0, 0 }, { "lda", 3, 2 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, - { "ld", 4 }, { "?", 0 }, { "st", 1 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, // 90 - { "ldl", 4 }, { "?", 0 }, { "stl", 1 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, + { "ld", 3, 2 }, { "?", 0, 0 }, { "st", 3, -2 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, // 90 + { "ldl", 3, 2 }, { "?", 0, 0 }, { "stl", 3, -2 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, - { "ldt", 4 }, { "?", 0 }, { "stt", 1 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, // a0 - { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, + { "ldt", 3, 2 }, { "?", 0, 0 }, { "stt", 3, -2 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, // a0 + { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "dcinva", 3, 1 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, - { "ldq", 4 }, { "?", 0 }, { "stq", 1 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, // b0 - { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, + { "ldq", 3, 2 }, { "?", 0, 0 }, { "stq", 3, -2 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, // b0 + { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, - { "ldib", 4 }, { "?", 0 }, { "stib", 1 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, // c0 - { "ldis", 4 }, { "?", 0 }, { "stis", 1 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, + { "ldib", 3, 2 }, { "?", 0, 0 }, { "stib", 3, -2 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, // c0 + { "ldis", 3, 2 }, { "?", 0, 0 }, { "stis", 3, -2 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, - { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, // d0 - { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, + { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, // d0 + { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, - { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, // e0 - { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, + { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, // e0 + { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, - { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, // f0 - { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 } + { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, // f0 + { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 } }; -const i960_disassembler::mnemonic_t i960_disassembler::mnem_reg[111] = +const i960_disassembler::mnemonic_t i960_disassembler::mnem_reg[197] = { - { "notbit", 0x580 }, { "and", 0x581 }, { "andnot", 0x582 }, { "setbit", 0x583 }, { "notand",0x584 }, - { "xor", 0x586 }, { "or", 0x587 }, { "nor", 0x588 }, { "xnor",0x589 }, { "not",0x58a }, - { "clrbit", 0x58c }, { "alterbit", 0x58f }, - { "addo", 0x590 }, { "addi",0x591 }, { "subo",0x592 }, { "subi",0x593 }, { "cmpob",0x594 }, { "shro",0x598 }, { "shrdi",0x59a }, { "shri",0x59b }, { "shlo",0x59c }, { "rotate",0x59d }, { "shli",0x59e }, - { "cmpo",0x5a0 }, { "cmpi",0x5a1 }, { "concmpo",0x5a2 }, { "concmpi",0x5a3 }, { "cmpinco",0x5a4 }, { "cmpinci",0x5a5 }, { "cmpdeco",0x5a6 }, { "cmpdeci",0x5a7 }, { "scanbyte",0x5ac }, { "bswap",0x5ad }, { "chkbit",0x5ae }, - { "addc",0x5b0 }, { "subc",0x5b2 }, - { "mov", 0x5cc }, - { "movl",0x5dc }, - { "movq",0x5fc }, - { "synmov",0x600 }, { "synmovq",0x602 }, - { "scanbit", 0x641 }, { "daddc", 0x642 }, { "dsubc", 0x643 }, { "dmovt", 0x644 }, { "modac",0x645 }, - { "modify",0x650 }, { "extract",0x651 }, { "modtc",0x654 }, { "modpc",0x655 }, - { "emul",0x670 }, { "ediv",0x671 }, { "cvtir", 0x674 }, { "cvtilr", 0x675 }, { "scalerl", 0x676 }, { "scaler", 0x677 }, - { "atanr",0x680 }, { "logepr", 0x681 }, { "logr", 0x682 }, { "remr", 0x683 }, { "cmpor", 0x684 }, { "cmpr", 0x685 }, { "sqrtr", 0x688 }, - { "expr", 0x689 }, { "logbnr", 0x68a }, { "roundr", 0x68b }, { "sinr", 0x68c }, { "cosr", 0x68d }, { "tanr", 0x68e }, { "classr", 0x68f }, - { "atanrl",0x690 }, { "logeprl", 0x691 }, { "logrl", 0x692 }, { "remrl", 0x693 }, { "cmporl", 0x694 }, { "cmprl", 0x695 }, { "sqrtrl", 0x698 }, - { "exprl", 0x699 }, { "logbnrl", 0x69a }, { "roundrl", 0x69b }, { "sinrl", 0x69c }, { "cosrl", 0x69d }, { "tanrl", 0x69e }, { "classrl", 0x69f }, - { "cvtri", 0x6c0 }, { "cvtril", 0x6c1 }, { "cvtzri", 0x6c2 }, { "cvtzril", 0x6c3 }, { "movr", 0x6c9 }, - { "movrl", 0x6d9 }, - { "movre", 0x6e1 }, { "cpysre", 0x6e2 }, { "cpyrsre", 0x6e3 }, - { "mulo", 0x701 }, { "remo",0x708 }, { "divo",0x70b }, - { "muli",0x741 }, { "remi",0x748 }, { "modi",0x749 }, { "divi",0x74b }, - { "divr",0x78b }, { "mulr",0x78c }, { "subr",0x78d }, { "addr",0x78f }, - { "divrl",0x79b }, { "mulrl",0x79c }, { "subrl",0x79d }, { "addrl",0x79f }, - { "ending_code",0 } -}; + { "notbit", 0x580, -3 }, { "and", 0x581, -3 }, { "andnot", 0x582, -3 }, { "setbit", 0x583, -3 }, // 58 + { "notand", 0x584, -3 }, { "xor", 0x586, -3 }, { "or", 0x587, -3 }, + { "nor", 0x588, -3 }, { "xnor", 0x589, -3 }, { "not", 0x58a, -2 }, { "ornot", 0x58b, -3 }, + { "clrbit", 0x58c, -3 }, { "notor", 0x58d, -3 }, { "nand", 0x58e, -3 }, { "alterbit", 0x58f, -3 }, -const char *const i960_disassembler::constnames[32] = -{ - "0x0", "0x1", "0x2", "0x3", "0x4", "0x5", "0x6", "0x7", "0x8", "0x9", "0xa", "0xb", "0xc", "0xd", "0xe", "0xf", - "0x10", "0x11", "0x12", "0x13", "0x14", "0x15", "0x16", "0x17", "0x18", "0x19", "0x1a", "0x1b", "0x1c", "0x1d", "0x1e", "0x1f" + { "addo", 0x590, -3 }, { "addi", 0x591, -3 }, { "subo", 0x592, -3 }, { "subi", 0x593, -3 }, // 59 + { "cmpob", 0x594, 2 }, { "cmpib", 0x595, 2 }, { "cmpos", 0x596, 2 }, { "cmpis", 0x597, 2 }, + { "shro", 0x598, -3 }, { "shrdi", 0x59a, -3 }, { "shri", 0x59b, -3 }, + { "shlo", 0x59c, -3 }, { "rotate", 0x59d, -3 }, { "shli", 0x59e, -3 }, + + { "cmpo", 0x5a0, 2 }, { "cmpi", 0x5a1, 2 }, { "concmpo", 0x5a2, 2 }, { "concmpi", 0x5a3, 2 }, // 5a + { "cmpinco", 0x5a4, -3 }, { "cmpinci", 0x5a5, -3 }, { "cmpdeco", 0x5a6, -3 }, { "cmpdeci", 0x5a7, -3 }, + { "scanbyte", 0x5ac, 2 }, { "bswap", 0x5ad, -2 }, { "chkbit", 0x5ae, 2 }, + + { "addc", 0x5b0, -3 }, { "subc", 0x5b2, -3 }, { "intdis", 0x5b4, 0 }, { "inten", 0x5b5, 0 }, // 5b + + { "mov", 0x5cc, -2 }, // 5c + + { "eshro", 0x5d8, -3 }, // 5d + { "movl", 0x5dc, -2 }, + + { "movt", 0x5ec, -2 }, // 5e + + { "movq", 0x5fc, -2 }, // 5f + + { "synmov", 0x600, 2 }, { "synmovl", 0x601, 2 }, { "synmovq", 0x602, 2 }, { "cmpstr", 0x603, 3 }, // 60 + { "movqstr", 0x604, -3 }, { "movstr", 0x605, -3 }, + + { "atmod", 0x610, 33 }, { "atadd", 0x612, 33 }, { "inspacc", 0x613, -2 }, // 61 + { "ldphy", 0x614, -2 }, { "synld", 0x615, -2 }, { "fill", 0x617, 3 }, + + { "sdma", 0x630, 3 }, { "udma", 0x631, 0 }, // 63 + + { "spanbit", 0x640, -2 }, { "scanbit", 0x641, -2 }, { "daddc", 0x642, -3 }, { "dsubc", 0x643, -3 }, // 64 + { "dmovt", 0x644, -2 }, { "modac", 0x645, 3 }, + + { "modify", 0x650, 33 }, { "extract", 0x651, 33 }, // 65 + { "modtc", 0x654, 33 }, { "modpc", 0x655, 33 }, { "receive", 0x656, -2 }, + { "intctl", 0x658, -2 }, { "sysctl", 0x659, 33 }, { "icctl", 0x65b, 33 }, + { "dcctl", 0x65c, 33 }, { "halt", 0x65d, 0 }, + + { "calls", 0x660, 1 }, { "send", 0x662, -3 }, { "sendserv", 0x663, 1 }, // 66 + { "resumprcs", 0x664, 1 }, { "schedprcs", 0x665, 1 }, { "saveprcs", 0x666, 0 }, + { "condwait", 0x668, 1 }, { "wait", 0x669, 1 }, { "signal", 0x66a, 1 }, { "mark", 0x66b, 0 }, + { "fmark", 0x66c, 0 }, { "flushreg", 0x66d, 0 }, { "syncf", 0x66f, 0 }, + + { "emul", 0x670, -3 }, { "ediv", 0x671, -3 }, { "ldtime", 0x671, -1 }, // 67 + { "cvtir", 0x674, -20 }, { "cvtilr", 0x675, -20 }, { "scalerl", 0x676, -30 }, { "scaler", 0x677, -30 }, + + { "atanr", 0x680, -30 }, { "logepr", 0x681, -30 }, { "logr", 0x682, -30 }, { "remr", 0x683, -30 }, // 68 + { "cmpor", 0x684, 20 }, { "cmpr", 0x685, 20 }, + { "sqrtr", 0x688, -20 }, { "expr", 0x689, -20 }, { "logbnr", 0x68a, -20 }, { "roundr", 0x68b, -20 }, + { "sinr", 0x68c, -20 }, { "cosr", 0x68d, -20 }, { "tanr", 0x68e, -20 }, { "classr", 0x68f, 10 }, + + { "atanrl", 0x690, -30 }, { "logeprl", 0x691, -30 }, { "logrl", 0x692, -30 }, { "remrl", 0x693, -30 }, // 69 + { "cmporl", 0x694, 20 }, { "cmprl", 0x695, 20 }, + { "sqrtrl", 0x698, -20 }, { "exprl", 0x699, -20 }, { "logbnrl", 0x69a, -20 }, { "roundrl", 0x69b, -20 }, + { "sinrl", 0x69c, -20 }, { "cosrl", 0x69d, -20 }, { "tanrl", 0x69e, -20 }, { "classrl", 0x69f, 10 }, + + { "cvtri", 0x6c0, -20 }, { "cvtril", 0x6c1, -20 }, { "cvtzri", 0x6c2, -20 }, { "cvtzril", 0x6c3, -20 }, // 6c + { "movr", 0x6c9, -20 }, + + { "movrl", 0x6d9, -20 }, // 6d + + { "movre", 0x6e1, -20 }, { "cpysre", 0x6e2, -30 }, { "cpyrsre", 0x6e3, -30 }, // 6e + { "movre", 0x6e9, -20 }, + + { "mulo", 0x701, -3 }, // 70 + { "remo", 0x708, -3 }, { "divo", 0x70b, -3 }, + + { "muli", 0x741, -3 }, // 74 + { "remi", 0x748, -3 }, { "modi", 0x749, -3 }, { "divi", 0x74b, -3 }, + + { "addono", 0x780, -3 }, { "addino", 0x781, -3 }, { "subono", 0x782, -3 }, { "subino", 0x783, -3 }, // 78 + { "selno", 0x784, -3 }, + { "divr", 0x78b, -30 }, { "mulr", 0x78c, -30 }, { "subr", 0x78d, -30 }, { "addr", 0x78f, -30 }, + + { "addog", 0x790, -3 }, { "addig", 0x791, -3 }, { "subog", 0x792, -3 }, { "subig", 0x793, -3 }, // 79 + { "selg", 0x794, -3 }, + { "divrl", 0x79b, -30 }, { "mulrl", 0x79c, -30 }, { "subrl", 0x79d, -30 }, { "addrl", 0x79f, -30 }, + + { "addoe", 0x7a0, -3 }, { "addie", 0x7a1, -3 }, { "suboe", 0x7a2, -3 }, { "subie", 0x7a3, -3 }, // 7a + { "sele", 0x7a4, -3 }, + + { "addoge", 0x7b0, -3 }, { "addige", 0x7b1, -3 }, { "suboge", 0x7b2, -3 }, { "subige", 0x7b3, -3 }, // 7b + { "selge", 0x7b4, -3 }, + + { "addol", 0x7c0, -3 }, { "addil", 0x7c1, -3 }, { "subol", 0x7c2, -3 }, { "subil", 0x7c3, -3 }, // 7c + { "sell", 0x7c4, -3 }, + + { "addone", 0x7d0, -3 }, { "addine", 0x7d1, -3 }, { "subone", 0x7d2, -3 }, { "subine", 0x7d3, -3 }, // 7d + { "selne", 0x7d4, -3 }, + + { "addole", 0x7e0, -3 }, { "addile", 0x7e1, -3 }, { "subole", 0x7e2, -3 }, { "subile", 0x7e3, -3 }, // 7e + { "selle", 0x7e4, -3 }, + + { "addoo", 0x7f0, -3 }, { "addio", 0x7f1, -3 }, { "suboo", 0x7f2, -3 }, { "subio", 0x7f3, -3 }, // 7f + { "selo", 0x7f4, -3 }, + + { "ending_code", 0, 0 } }; const char *const i960_disassembler::regnames[32] = @@ -101,80 +180,355 @@ const char *const i960_disassembler::regnames[32] = "g0","g1","g2","g3", "g4","g5","g6","g7", "g8","g9","g10","g11", "g12","g13","g14","fp", }; -#define REG_DST regnames[dst] -#define REG_ABASE regnames[abase] -#define REG_REG2 regnames[reg2] -#define REG_COBR_SRC1 ((iCode & 0x2000) ? constnames[COBRSRC1] : regnames[COBRSRC1]) -#define REG_COBR_SRC2 regnames[COBRSRC2] -#define NEM mnemonic[op].mnem - -// REG format -#define SRC1 (iCode & 0x1f) -#define S1 ((iCode >> 5) & 0x1) -#define S2 ((iCode >> 6) & 0x1) -#define OP2 ((iCode >> 7) & 0xf) -#define M1 ((iCode >> 11) & 0x1) -#define M2 ((iCode >> 12) & 0x1) -#define M3 ((iCode >> 13) & 0x1) -#define SRC2 ((iCode >> 14) & 0x1f) -#define DST ((iCode >> 19) & 0x1f) -#define OP ((iCode >> 24) & 0xff) - -// COBR format -#define COBRSRC1 ((iCode >> 19) & 0x1f) -#define COBRSRC2 ((iCode >> 14) & 0x1f) - -std::string i960_disassembler::dis_decode_reg(u32 iCode, unsigned char cnt) +const char *const i960_disassembler::fprnames[32] = { - std::string src1, src2, dst; + "fp0","fp1","fp2","fp3", "?","?","?","?", "?","?","?","?", "?","?","?","?", + "+0.0","?","?","?", "?","?","+1.0","?", "?","?","?","?", "?","?","?","?", +}; - if (S1) - src1 = ""; - else +offs_t i960_disassembler::dis_decode_invalid(std::ostream &stream, u32 iCode) +{ + /* + u8 op = (unsigned char) (iCode >> 24); + u8 op2 = (unsigned char) (iCode >> 7)&0xf; + u8 model = (unsigned char) (iCode >> 10) &0x3; + u8 modeh = (unsigned char) (iCode >> 12) &0x3; + return util::stream_format(stream, "%s %08lx %02x:%01x %1x %1x", mnemonic[op].mnem, iCode, op, op2, modeh, model); + */ + //util::stream_format(stream, ".word\t0x%08x", iCode); + util::stream_format(stream, "? %08x", iCode); + + return 4; +} + +offs_t i960_disassembler::dis_decode_ctrl(std::ostream &stream, u32 iCode, u32 ip, signed char cnt) +{ + u8 op = (unsigned char) (iCode >> 24); + //u8 t = (unsigned char) (iCode >> 1 & 1); // Cx, Hx, Rx - branch prediction (ignored for now) + u32 disp = iCode & 0x00fffffc; + + // check bit 0 + if ((iCode & 1) != 0x0) return dis_decode_invalid(stream, iCode); + + switch(cnt) { - if(M1) - src1 = util::string_format("0x%lx", SRC1); - else - src1 = util::string_format("%s", regnames[SRC1]); + case 0: // no operand + util::stream_format(stream, "%s", mnemonic[op].mnem); + break; + case 1: // 1 operand + util::stream_format(stream, "%-8s%08lx", mnemonic[op].mnem, ((((s32)disp) << 8) >> 8) + (ip)); + break; + default: + return dis_decode_invalid(stream, iCode); + break; } - if (S2) - src2 = ",reserved"; - else + return 4; +} + +offs_t i960_disassembler::dis_decode_cobr(std::ostream &stream, u32 iCode, u32 ip, signed char cnt) +{ + u8 op = (unsigned char) (iCode >> 24); + u8 src1 = (unsigned char) (iCode >> 19) & 0x1f; + u8 src2 = (unsigned char) (iCode >> 14) & 0x1f; + u8 m1 = (unsigned char) (iCode >> 13 & 1); + //u8 t = (unsigned char) (iCode >> 1 & 1); // Cx, Hx, Rx - branch prediction + u8 s2 = (unsigned char) iCode & 1; // Cx, Hx, Rx - src2 = special function register + u32 disp = iCode & 0x1ffc; + + std::string op1, op2, op3; + + switch(cnt) { - if(M2) - src2 = util::string_format(",0x%lx", SRC2); - else - src2 = util::string_format(",%s", regnames[SRC2]); + case 1: // 1 operand (test*) + // For the test-if instructions, only the srcl field is used. Here, this field specifies a destination global or local register (ml is ignored). + util::stream_format(stream, "%-8s%s", mnemonic[op].mnem, regnames[src1]); + break; + case 3: // 3 operands + // TODO m1 set differs on Mx, Kx, Jx, Rx references (literal) and Hx reference (sf-register) + if (m1) op1 = util::string_format("%d", src1); + else op1 = util::string_format("%s", regnames[src1]); + if (s2) op2 = util::string_format("sf%d", src2); + else op2 = util::string_format("%s", regnames[src2]); + op3 = util::string_format("0x%lx", ((((s32)disp) << 19) >> 19) + (ip)); + + util::stream_format(stream, "%-8s%s,%s,%s", mnemonic[op].mnem, op1, op2, op3); + break; + default: + return dis_decode_invalid(stream, iCode); + break; } - if(M3) - dst = ""; - else - dst = util::string_format(",%s", regnames[DST]); + return 4; +} - if (cnt == 1) - return util::string_format("%s%s", src1, dst); - else - return util::string_format("%s%s%s", src1, src2, dst); +offs_t i960_disassembler::dis_decode_mema(std::ostream &stream, u32 iCode, signed char cnt) +{ + u8 op = (unsigned char) (iCode >> 24); + u8 srcdst = (unsigned char) (iCode >> 19) & 0x1f; + u8 abase = (unsigned char) (iCode >> 14) & 0x1f; + u8 mode = (unsigned char) (iCode >> 13) & 0x1; + u32 offset = iCode & 0xfff; + + switch(mode) + { + case 0: + // offset + switch(cnt) + { + case 1: // bx/callx + util::stream_format(stream, "%-8s0x%lx", mnemonic[op].mnem, offset); + break; + case 2: // load + util::stream_format(stream, "%-8s0x%lx,%s", mnemonic[op].mnem, offset, regnames[srcdst]); + break; + case -2: // store + util::stream_format(stream, "%-8s%s,0x%lx", mnemonic[op].mnem, regnames[srcdst], offset); + break; + default: + return dis_decode_invalid(stream, iCode); + break; + } + break; + case 1: + // (abase) + offset + switch(cnt) + { + case 1: // bx/callx + util::stream_format(stream, "%-8s0x%lx(%s)", mnemonic[op].mnem, offset, regnames[abase]); + break; + case 2: // load + util::stream_format(stream, "%-8s0x%lx(%s),%s", mnemonic[op].mnem, offset, regnames[abase], regnames[srcdst]); + break; + case -2: // store + util::stream_format(stream, "%-8s%s,0x%lx(%s)", mnemonic[op].mnem, regnames[srcdst], offset, regnames[abase]); + break; + default: + return dis_decode_invalid(stream, iCode); + break; + } + break; + default: + return dis_decode_invalid(stream, iCode); + break; + } + + return 4; +} + +offs_t i960_disassembler::dis_decode_memb(std::ostream &stream, u32 iCode, u32 ip, u32 disp, signed char cnt) +{ + u8 op = (unsigned char) (iCode >> 24); + u8 srcdst = (unsigned char) (iCode >> 19) & 0x1f; + u8 abase = (unsigned char) (iCode >> 14) & 0x1f; + u8 mode = (unsigned char) (iCode >> 10) & 0xf; + u8 scale = (unsigned char) (iCode >> 7) & 0x7; + u8 index = (unsigned char) iCode & 0x1f; + + offs_t IPinc; + std::string efa; + + // check bits 5 and 6 + if ((iCode & 0x60) != 0x0) return dis_decode_invalid(stream, iCode); + + // check scale + if (scale > 4) return dis_decode_invalid(stream, iCode); + + if ((mode == 0x5) || (mode >= 0xc)) IPinc = 8; + else IPinc = 4; + + switch(mode) + { + case 0x4: // (abase) + efa = util::string_format("(%s)", regnames[abase]); + break; + case 0x5: // (IP) + displacement + 8 + efa = util::string_format("0x%x", ip + disp + 8); + break; + case 0x6: // reserved + return dis_decode_invalid(stream, iCode); + break; + case 0x7: // (abase) + (index) * 2^scale + if (scale == 0) efa = util::string_format("(%s)[%s]", regnames[abase], regnames[index]); + else efa = util::string_format("(%s)[%s*%ld]", regnames[abase], regnames[index], 1 << scale); + break; + case 0xc: // displacement + efa = util::string_format("0x%x", disp); + break; + case 0xd: // (abase) + displacement + efa = util::string_format("0x%x(%s)", disp, regnames[abase]); + break; + case 0xe: // (index) * 2^scale + displacement + if (scale == 0) efa = util::string_format("0x%x[%s]", disp, regnames[index]); + else efa = util::string_format("0x%x[%s*%ld]", disp, regnames[index], 1 << scale); + break; + case 0xf: // (abase) + (index) * 2^scale + displacement + if (scale == 0) efa = util::string_format("0x%x(%s)[%s]", disp, regnames[abase], regnames[index]); + else efa = util::string_format("0x%x(%s)[%s*%ld]", disp, regnames[abase], regnames[index], 1 << scale); + break; + default: + return dis_decode_invalid(stream, iCode); + break; + } + + switch (cnt) + { + case 1: // bx/callx + util::stream_format(stream, "%-8s%s", mnemonic[op].mnem, efa); + break; + case 2: // load + util::stream_format(stream, "%-8s%s,%s", mnemonic[op].mnem, efa, regnames[srcdst]); + break; + case -2: // store + util::stream_format(stream, "%-8s%s,%s", mnemonic[op].mnem, regnames[srcdst], efa); + break; + default: + return dis_decode_invalid(stream, iCode); + break; + } + + return IPinc; +} + +offs_t i960_disassembler::dis_decode_reg(std::ostream &stream, u32 iCode) +{ + u16 op = (unsigned short) ((iCode >> 20) & 0xff0) | ((iCode >> 7) & 0xf); + u8 srcdst = (unsigned char) (iCode >> 19) & 0x1f; + u8 src2 = (unsigned char) (iCode >> 14) & 0x1f; + u8 m3 = (unsigned char) (iCode >> 13) & 1; + u8 m2 = (unsigned char) (iCode >> 12) & 1; + u8 m1 = (unsigned char) (iCode >> 11) & 1; + u8 s2 = (unsigned char) (iCode >> 6) & 1; + u8 s1 = (unsigned char) (iCode >> 5) & 1; + u8 src1 = (unsigned char) iCode & 0x1f; + + u8 sm1 = ((s1 << 1) | m1); + u8 sm2 = ((s2 << 1) | m2); + u32 i = 0; + std::string op1, op2, op3; + + while(mnem_reg[i].type != 0) + { + if (mnem_reg[i].type == op) break; + i++; + } + if (mnem_reg[i].type != op) return dis_decode_invalid(stream, iCode); + + switch (sm1) + { + case 0: // neither set + op1 = util::string_format("%s", regnames[src1]); + break; + case 1: // M1 set + op1 = util::string_format("%d", src1); + break; + case 2: // S1 set + op1 = util::string_format("sf%d", src1); + break; + case 3: // M1 and S1 set + default: + return dis_decode_invalid(stream, iCode); + break; + } + + switch (sm2) + { + case 0: // neither set + op2 = util::string_format("%s", regnames[src2]); + break; + case 1: // M2 set + op2 = util::string_format("%d", src2); + break; + case 2: // S2 set + op2 = util::string_format("sf%d", src2); + break; + case 3: // M2 and S2 set + default: + return dis_decode_invalid(stream, iCode); + break; + } + + switch (mnem_reg[i].flags) + { + case 0: // no operand + util::stream_format(stream, "%-8s", mnem_reg[i].mnem); + break; + case 1: // single operand, which is NOT a destination. + util::stream_format(stream, "%-8s%s", mnem_reg[i].mnem, op1); + break; + case -1: // single operand, which IS a destination. + if (m3) op3 = util::string_format("sf%d", srcdst); + else op3 = util::string_format("%s", regnames[srcdst]); + util::stream_format(stream, "%-8s%s", mnem_reg[i].mnem, op3); + break; + case 2: // 2 operands, the 2nd of which is NOT a destination. + util::stream_format(stream, "%-8s%s,%s", mnem_reg[i].mnem, op1, op2); + break; + case -2: // 2 operands, the 2nd of which IS a destination. + if (m3) op3 = util::string_format("sf%d", srcdst); + else op3 = util::string_format("%s", regnames[srcdst]); + util::stream_format(stream, "%-8s%s,%s", mnem_reg[i].mnem, op1, op3); + break; + case 3: // 3 operands, the 3rd of which is NOT a destination. + if (m3) op3 = util::string_format("%d", srcdst); + else op3 = util::string_format("%s", regnames[srcdst]); + util::stream_format(stream, "%-8s%s,%s,%s", mnem_reg[i].mnem, op1, op2, op3); + break; + case -3: // 3 operands, the 3rd of which IS a destination. + if (m3) op3 = util::string_format("sf%d", srcdst); + else op3 = util::string_format("%s", regnames[srcdst]); + util::stream_format(stream, "%-8s%s,%s,%s", mnem_reg[i].mnem, op1, op2, op3); + break; + case 33: // 3 operands, the 3rd of which is source and destination. + // m3 must NOT be set for src/dst type + if (m3) return dis_decode_invalid(stream, iCode); + op3 = util::string_format("%s", regnames[srcdst]); + util::stream_format(stream, "%-8s%s,%s,%s", mnem_reg[i].mnem, op1, op2, op3); + break; + + // floating point opcodes + case 10: // single operand, which is NOT a destination. + if (m1) op1 = util::string_format("%s", fprnames[src1]); + else op1 = util::string_format("%s", regnames[src1]); + util::stream_format(stream, "%-8s%s", mnem_reg[i].mnem, op1); + break; + case 20: // 2 operands, the 2nd of which is NOT a destination. + if (m1) op1 = util::string_format("%s", fprnames[src1]); + else op1 = util::string_format("%s", regnames[src1]); + if (m2) op2 = util::string_format("%s", fprnames[src2]); + else op2 = util::string_format("%s", regnames[src2]); + util::stream_format(stream, "%-8s%s,%s", mnem_reg[i].mnem, op1, op2); + break; + case -20: // 2 operands, the 2nd of which IS a destination. + if (m1) op1 = util::string_format("%s", fprnames[src1]); + else op1 = util::string_format("%s", regnames[src1]); + if (m3) op3 = util::string_format("%s", fprnames[srcdst]); + else op3 = util::string_format("%s", regnames[srcdst]); + util::stream_format(stream, "%-8s%s,%s", mnem_reg[i].mnem, op1, op3); + break; + case -30: // 3 operands, the 3rd of which IS a destination. + if (m1) op1 = util::string_format("%s", fprnames[src1]); + else op1 = util::string_format("%s", regnames[src1]); + if (m2) op2 = util::string_format("%s", fprnames[src2]); + else op2 = util::string_format("%s", regnames[src2]); + if (m3) op3 = util::string_format("%s", fprnames[srcdst]); + else op3 = util::string_format("%s", regnames[srcdst]); + util::stream_format(stream, "%-8s%s,%s,%s", mnem_reg[i].mnem, op1, op2, op3); + break; + default: + return dis_decode_invalid(stream, iCode); + break; + } + + return 4; } offs_t i960_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { u32 IP = pc; - u32 iCode = opcodes.r32(IP); - u8 op = (unsigned char) (iCode >> 24); - u8 op2 = (unsigned char) (iCode >> 7)&0xf; - u16 opc = 0; - u32 i = 0; - u8 model = (unsigned char) (iCode >> 10) &0x3; - u8 modeh = (unsigned char) (iCode >> 12) &0x3; - //mode = (unsigned char) (iCode >> 10) &0x7; - u8 dst = (unsigned char) (iCode >> 19) &0x1f; - u8 abase = (unsigned char) (iCode>>14)&0x1f; - u8 reg2 = (unsigned char) (iCode)&0x1f; + u8 op = (unsigned char) (iCode >> 24); offs_t IPinc = 4; offs_t disflags = 0; @@ -186,157 +540,25 @@ offs_t i960_disassembler::disassemble(std::ostream &stream, offs_t pc, const dat switch(mnemonic[op].type) { - case 0: // not yet implemented - util::stream_format(stream, "%s %02x:%01x %08lx %1x %1x",mnemonic[op].mnem,op,op2,iCode, modeh, model); + case 0: // invalid / not yet implemented + IPinc = dis_decode_invalid(stream, iCode); break; - case 1: // memory access (write) - switch(modeh) - { - case 0: - util::stream_format(stream, "%-8s%s,0x%lx",NEM,REG_DST, iCode&0xfff); - break; - case 1: - switch (model) - { - case 0: - util::stream_format(stream, "%-8s%s,(%s)",NEM,REG_DST, REG_ABASE); - break; - case 3: - util::stream_format(stream, "%-8s%s,(%s)[%s*%ld]",NEM,REG_DST, REG_ABASE,REG_REG2,1<<((iCode>>7)&0x7)); - break; - default: - util::stream_format(stream, "%s %02x:%01x %08lx %1x %1x",mnemonic[op].mnem,op,op2,iCode, modeh, model); - break; - } - break; - case 2: - util::stream_format(stream, "%-8s%s,0x%lx(%s)",NEM,REG_DST, iCode&0xfff,REG_ABASE); - break; - case 3: - switch (model) - { - case 0: - util::stream_format(stream, "%-8s%s,0x%x",NEM,REG_DST, opcodes.r32(IP + 4)); - IPinc = 8; - break; - case 1: - util::stream_format(stream, "%-8s%s,0x%x(%s)",NEM,REG_DST, opcodes.r32(IP + 4),REG_ABASE); - IPinc = 8; - break; - case 2: - util::stream_format(stream, "%-8s%s,0x%x[%s*%ld]",NEM,REG_DST, opcodes.r32(IP + 4),REG_REG2,1<<((iCode>>7)&0x7)); - IPinc = 8; - break; - case 3: - util::stream_format(stream, "%-8s%s,0x%x(%s)[%s*%ld]",NEM,REG_DST, opcodes.r32(IP + 4),REG_ABASE,REG_REG2,1<<((iCode>>7)&0x7)); - IPinc = 8; - break; - default: - util::stream_format(stream, "%s %02x:%01x %08lx %1x %1x",mnemonic[op].mnem,op,op2,iCode, modeh, model); - break; - } - break; - default: - util::stream_format(stream, "%s %02x:%01x %08lx %1x %1x",mnemonic[op].mnem,op,op2,iCode, modeh, model); - break; - } + case 1: // CTRL format + IPinc = dis_decode_ctrl(stream, iCode, IP, mnemonic[op].flags); break; - case 2: - i = 0; - opc = op<<4|op2; - - while(mnem_reg[i].type != 0) - { - if (mnem_reg[i].type == opc) break; - i++; - } - - if (mnem_reg[i].type == opc) util::stream_format(stream, "%-8s%s", mnem_reg[i].mnem,dis_decode_reg(iCode,1)); - else util::stream_format(stream, "%s %02x:%01x %08lx %1x %1x",mnemonic[op].mnem,op,op2,iCode, modeh, model); + case 2: // COBR compare and branch type + IPinc = dis_decode_cobr(stream, iCode, IP, mnemonic[op].flags); break; - case 3: - i = 0; - opc = op<<4|op2; - - while(mnem_reg[i].type != 0) - { - if (mnem_reg[i].type == opc) break; - i++; - } - - if (mnem_reg[i].type == opc) util::stream_format(stream, "%-8s%s", mnem_reg[i].mnem,dis_decode_reg(iCode,0)); - else util::stream_format(stream, "%s %02x:%01x %08lx %1x %1x",mnemonic[op].mnem,op,op2,iCode, modeh, model); + case 3: // MEM format + if ((iCode >> 12) & 0x1) + // MEMB format + IPinc = dis_decode_memb(stream, iCode, IP, opcodes.r32(IP + 4), mnemonic[op].flags); + else + // MEMA format + IPinc = dis_decode_mema(stream, iCode, mnemonic[op].flags); break; - case 4: // memory access (read) - switch(modeh) - { - case 0: - util::stream_format(stream, "%-8s0x%lx,%s",NEM,iCode&0xfff,REG_DST); - break; - case 1: - switch (model) - { - case 0: - util::stream_format(stream, "%-8s(%s),%s",NEM,REG_ABASE,REG_DST); - break; - case 3: - util::stream_format(stream, "%-8s(%s)[%s*%ld],%s",NEM,REG_ABASE,REG_REG2,1<<((iCode>>7)&0x7),REG_DST); - break; - default: - util::stream_format(stream, "%s %02x:%01x %08lx %1x %1x",mnemonic[op].mnem,op,op2,iCode, modeh, model); - break; - } - break; - case 2: - util::stream_format(stream, "%-8s0x%lx(%s),%s",NEM,iCode&0xfff,REG_ABASE,REG_DST); - break; - case 3: - switch (model) - { - case 0: - util::stream_format(stream, "%-8s0x%x,%s",NEM,opcodes.r32(IP + 4),REG_DST); - IPinc = 8; - break; - case 1: - util::stream_format(stream, "%-8s0x%x(%s),%s",NEM,opcodes.r32(IP + 4),REG_ABASE,REG_DST); - IPinc = 8; - break; - case 2: - util::stream_format(stream, "%-8s0x%x[%s*%ld],%s",NEM,opcodes.r32(IP + 4),REG_REG2,1<<((iCode>>7)&0x7),REG_DST); - IPinc = 8; - break; - case 3: - util::stream_format(stream, "%-8s0x%x(%s)[%s*%ld],%s",NEM, opcodes.r32(IP + 4),REG_ABASE,REG_REG2,1<<((iCode>>7)&0x7),REG_DST); - IPinc = 8; - break; - default: - util::stream_format(stream, "%s %02x:%01x %08lx %1x %1x",mnemonic[op].mnem,op,op2,iCode, modeh, model); - break; - } - break; - default: - util::stream_format(stream, "%s %02x:%01x %08lx %1x %1x",mnemonic[op].mnem,op,op2,iCode, modeh, model); - break; - } - break; - - case 6: // bitpos and branch type - util::stream_format(stream, "%-8s%ld,%s,0x%lx",NEM, COBRSRC1, REG_COBR_SRC2,((((s32)iCode&0x00fffffc)<<19)>>19) + (IP)); - break; - case 7: // compare and branch type - util::stream_format(stream, "%-8s%s,%s,0x%lx",NEM,REG_COBR_SRC1,REG_COBR_SRC2,((((s32)iCode&0x00fffffc)<<19)>>19) + (IP)); - break; - case 8: // target type - util::stream_format(stream, "%-8s%08lx",NEM,((((s32)iCode&0x00fffffc)<<8)>>8) + (IP)); - break; - case 9: // no operands - util::stream_format(stream, "%s",NEM); - break; - case 10: // TEST type: register only - util::stream_format(stream, "%s %s", NEM, REG_DST); - break; - case 11: // workaround to match users guide - util::stream_format(stream, "%-8s(%s)",NEM, REG_ABASE); + case 4: // REG format + IPinc = dis_decode_reg(stream, iCode); break; default: stream << "???"; diff --git a/src/devices/cpu/i960/i960dis.h b/src/devices/cpu/i960/i960dis.h index b3620371545..16941815acd 100644 --- a/src/devices/cpu/i960/i960dis.h +++ b/src/devices/cpu/i960/i960dis.h @@ -19,14 +19,20 @@ private: { const char *mnem; unsigned short type; + signed char flags; }; static const mnemonic_t mnemonic[256]; - static const mnemonic_t mnem_reg[111]; - static const char *const constnames[32]; + static const mnemonic_t mnem_reg[197]; static const char *const regnames[32]; + static const char *const fprnames[32]; - std::string dis_decode_reg(u32 iCode, unsigned char cnt); + offs_t dis_decode_invalid(std::ostream &stream, u32 iCode); + offs_t dis_decode_ctrl(std::ostream &stream, u32 iCode, u32 ip, signed char cnt); + offs_t dis_decode_cobr(std::ostream &stream, u32 iCode, u32 ip, signed char cnt); + offs_t dis_decode_mema(std::ostream &stream, u32 iCode, signed char cnt); + offs_t dis_decode_memb(std::ostream &stream, u32 iCode, u32 ip, u32 disp, signed char cnt); + offs_t dis_decode_reg(std::ostream &stream, u32 iCode); };