summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/cpu/i960/i960dis.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/cpu/i960/i960dis.cpp')
-rw-r--r--src/devices/cpu/i960/i960dis.cpp696
1 files changed, 489 insertions, 207 deletions
diff --git a/src/devices/cpu/i960/i960dis.cpp b/src/devices/cpu/i960/i960dis.cpp
index 6f207494124..7d9d26b32ad 100644
--- a/src/devices/cpu/i960/i960dis.cpp
+++ b/src/devices/cpu/i960/i960dis.cpp
@@ -9,87 +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)
+*/
+// TODO: make this table more legible?
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", 3 }, { "?", 0 }, { "5F", 3 },
+ { "?", 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 },
- { "synmov", 1 }, { "?", 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", 1 }, { "?", 0 }, { "stob", 1 }, { "?", 0 }, { "bx", 1 }, { "balx", 1 }, { "callx", 1 }, { "?", 0 }, // 80
- { "ldos", 1 }, { "?", 0 }, { "stos", 1 }, { "?", 0 }, { "lda", 1 }, { "?", 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", 1 }, { "?", 0 }, { "st", 1 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, // 90
- { "ldl", 1 }, { "?", 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", 1 }, { "?", 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 }, { "?", 0, 0 }, { "dcinva", 3, 1 }, { "?", 0, 0 }, { "?", 0, 0 },
- { "ldq", 1 }, { "?", 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", 1 }, { "?", 0 }, { "stib", 1 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, // c0
- { "ldis", 1 }, { "?", 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[100] =
+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 },
- { "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 },
- { "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 },
- { "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] =
@@ -98,187 +180,387 @@ 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
- {
- if(M1)
- src1 = util::string_format("0x%lx", SRC1);
- else
- src1 = util::string_format("%s", regnames[SRC1]);
- }
+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);
- if (S2)
- src2 = "reserved";
- else
+ 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(M2)
- src2 = util::string_format("0x%lx,", SRC2);
- else
- src2 = util::string_format("%s,", regnames[SRC2]);
+ 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, util::sext(disp, 24) + (ip));
+ break;
+ default:
+ return dis_decode_invalid(stream, iCode);
+ break;
}
- if(M3)
- dst = "";
- else
- dst = util::string_format("%s,", regnames[DST]);
-
- if (cnt == 1)
- return util::string_format("%s%s", dst, src1);
- else
- return util::string_format("%s%s%s", dst, src2, src1);
+ return 4;
}
-offs_t i960_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer &params)
+offs_t i960_disassembler::dis_decode_cobr(std::ostream &stream, u32 iCode, u32 ip, signed char cnt)
{
- 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 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;
- 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;
+ std::string op1, op2, op3;
- offs_t IPinc = 4;
- offs_t disflags = 0;
+ switch(cnt)
+ {
+ 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", util::sext(disp, 13) + (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 (op == 0x09 || op == 0x0b || op == 0x66 || op == 0x85 || op == 0x86)
- disflags = STEP_OVER;
- else if (op == 0x0a)
- disflags = STEP_OUT;
+ return 4;
+}
- switch(mnemonic[op].type)
+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: // not yet implemented
- util::stream_format(stream, "%s %02x:%01x %08lx %1x %1x",mnemonic[op].mnem,op,op2,iCode, modeh, model);
- break;
- case 1: // memory access
- switch(modeh)
+ case 0:
+ // offset
+ switch(cnt)
{
- 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;
- }
+ case 1: // bx/callx
+ util::stream_format(stream, "%-8s0x%lx", mnemonic[op].mnem, offset);
break;
- case 2:
- util::stream_format(stream, "%-8s%s,0x%lx(%s)",NEM,REG_DST, iCode&0xfff,REG_ABASE);
+ case 2: // load
+ util::stream_format(stream, "%-8s0x%lx,%s", mnemonic[op].mnem, offset, regnames[srcdst]);
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;
- }
+ case -2: // store
+ util::stream_format(stream, "%-8s%s,0x%lx", mnemonic[op].mnem, regnames[srcdst], offset);
break;
default:
- util::stream_format(stream, "%s %02x:%01x %08lx %1x %1x",mnemonic[op].mnem,op,op2,iCode, modeh, model);
+ return dis_decode_invalid(stream, iCode);
break;
}
break;
- case 2:
- i = 0;
- opc = op<<4|op2;
-
- while(mnem_reg[i].type != 0)
+ case 1:
+ // (abase) + offset
+ switch(cnt)
{
- if (mnem_reg[i].type == opc) break;
- i++;
+ 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;
- 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);
+ 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 3:
- i = 0;
- opc = op<<4|op2;
+ 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;
+ }
- while(mnem_reg[i].type != 0)
- {
- if (mnem_reg[i].type == opc) break;
- i++;
- }
+ 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;
+}
- 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);
+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;
+ }
- 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));
+ switch (sm2)
+ {
+ case 0: // neither set
+ op2 = util::string_format("%s", regnames[src2]);
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));
+ case 1: // M2 set
+ op2 = util::string_format("%d", src2);
break;
- case 8: // target type
- util::stream_format(stream, "%-8s%08lx",NEM,((((s32)iCode&0x00fffffc)<<8)>>8) + (IP));
+ case 2: // S2 set
+ op2 = util::string_format("sf%d", src2);
break;
- case 9: // no operands
- util::stream_format(stream, "%s",NEM);
+ 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 &params)
+{
+ u32 IP = pc;
+ u32 iCode = opcodes.r32(IP);
+
+ u8 op = (unsigned char) (iCode >> 24);
+
+ offs_t IPinc = 4;
+ offs_t disflags = 0;
+
+ if (op == 0x09 || op == 0x0b || op == 0x66 || op == 0x85 || op == 0x86)
+ disflags = STEP_OVER;
+ else if (op == 0x0a)
+ disflags = STEP_OUT;
+ else if ((op & 0xd8) == 0x10 || (op > 0x38 && op < 0x3f))
+ disflags = STEP_COND;
+
+ switch(mnemonic[op].type)
+ {
+ case 0: // invalid / not yet implemented
+ IPinc = dis_decode_invalid(stream, iCode);
+ break;
+ case 1: // CTRL format
+ IPinc = dis_decode_ctrl(stream, iCode, IP, mnemonic[op].flags);
+ break;
+ case 2: // COBR compare and branch type
+ IPinc = dis_decode_cobr(stream, iCode, IP, mnemonic[op].flags);
+ break;
+ 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 10: // TEST type: register only
- util::stream_format(stream, "%s %s", NEM, REG_DST);
+ case 4: // REG format
+ IPinc = dis_decode_reg(stream, iCode);
break;
default:
stream << "???";