summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/cpu/ssp1610/ssp1610d.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/emu/cpu/ssp1610/ssp1610d.c')
-rw-r--r--src/emu/cpu/ssp1610/ssp1610d.c532
1 files changed, 532 insertions, 0 deletions
diff --git a/src/emu/cpu/ssp1610/ssp1610d.c b/src/emu/cpu/ssp1610/ssp1610d.c
new file mode 100644
index 00000000000..a22a16e4e7f
--- /dev/null
+++ b/src/emu/cpu/ssp1610/ssp1610d.c
@@ -0,0 +1,532 @@
+/*
+
+ SSP1610 disassembler
+ written by Pierpaolo Prazzoli
+
+*/
+
+#include <math.h>
+#include "debugger.h"
+#include "cpuintrf.h"
+
+
+static const char* reg[] =
+{
+ "-", "X", "Y", "A", "ST", "STACK", "PC", "P", "AL", "?", "?", "XST", "PL", "?", "?", "SRCR", "BRCR", "BRER",
+ "XRD0", "XRD1", "AE", "DIOR", "GR22", "GR23", "EXT0", "EXT1", "EXT2", "EXT3", "EXT4", "EXT5", "EXT6", "EXT7"
+};
+
+static const char* rij[] =
+{
+ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7"
+};
+
+static const char* erij[] =
+{
+ "er0", "er1", "er2", "er3", "er4", "er5", "er6", "er7"
+};
+
+static const char* modifier[] =
+{
+ "", "+!", "-", "+"
+};
+
+static const char* cond[] =
+{
+ "always", "always", "RESERVED", "RESERVED", "gpi0=0", "gpi0=1", "gpi1=0", "gpi1=1", "l=0", "l=1", "z=0", "z=1", "ov=0", "ov=1", "n=0", "n=1",
+ "diof=0", "diof=1", "gpi2=0", "gpi2=1", "gpi3=0", "gpi3=1", "RESERVED", "RESERVED", "RESERVED", "RESERVED", "RESERVED", "RESERVED", "RESERVED", "RESERVED", "RESERVED", "RESERVED"
+};
+
+static const char* acc_op[] =
+{
+ "ror", "rol", "shr", "shl", "inc", "dec", "neg", "abs"
+};
+
+// pag. 81 uses different addresses!
+static const char* flag_op[] =
+{
+ "?", "?", "resl", "setl", "resie", "setie", "?", "?", "resop", "setop", "?", "?", "?", "?", "res", "set"
+};
+
+
+static const char* st_mod[] =
+{
+ "macs", "rpl", "gpo", "rb", "gpo0", "gpo1", "gpo2", "gpo3", "wte", "diof", "bre", "reserved", "reserved", "reserved", "reserved", "reserved"
+};
+
+
+#define BIT_B ((op >> 8) & 1)
+#define RIJ rij[(BIT_B << 2) + (op & 3)]
+#define RI(i) rij[(i) & 3]
+#define RJ(i) rij[((i) & 3) + 4]
+#define MODIFIER(i) modifier[(i) & 3]
+#define MODIFIER_LOW MODIFIER(op >> 2)
+#define MODIFIER_HIGH MODIFIER(op >> 6)
+#define COND cond[(op >> 4) & 0xf]
+
+static offs_t base_pc;
+static const UINT8 *base_oprom;
+#define READ_OP_DASM(p) ((base_oprom[(p) - base_pc] << 8) | base_oprom[(p) + 1 - base_pc])
+
+//TODO:
+// - add special Short-form Direct Addressing for r3 and r7
+// - support DASM flags
+
+unsigned dasm_ssp1610(char *buffer, unsigned pc, const UINT8 *oprom)
+{
+ UINT16 op;
+ UINT8 op_num;
+ int size = 1;
+ int flags = 0;
+
+ base_pc = pc;
+ base_oprom = oprom;
+
+ op = READ_OP_DASM(pc);
+ op_num = op >> 9;
+
+ // .....overlapping opcodes....
+ //
+ // ldi simm ?
+ // ld d, (a) ?
+ // mset reg, (ri), b ? overlaps other opcodes
+ // mset (rj), (ri), b ?
+ // repb simm/srcr, imm ?
+ // reps simm/srcr ?
+ // subi (rij)/erij/reg,imm,t ?
+ /*
+ // mod x, nimm, n
+ case 0x11:
+ sprintf(buffer, "mod x, %X, %d", op & 0xf, (op >> 4) & 1);
+ break;
+
+ // mset (rj), (ri), ss
+ case 0x18, 0x19: // ss order?
+ sprintf(buffer, "mset (%s%s), (%s%s), %d%d", RJ(op >> 5), MODIFIER(op >> 7), RI(op), MODIFIER_LOW, (op >> 9) & 1, (op >> 4) & 1);
+ break;
+
+ // mod st, bs, nimm
+ case 0x28: //? docs say 0x24
+ sprintf(buffer, "mod st, %s, %x", st_mod[(op >> 5) & 0xf], op & 0xf);
+ break;
+ */
+
+ switch( op_num )
+ {
+
+ //????????????????????
+
+ // ldi simm
+// case 0x08:
+// sprintf(buffer, "ldi %X", op & 0xff);
+// break;
+
+ // maybe
+ // mod st, bs, nimm
+ case 0x25: //? docs say 0x24
+ sprintf(buffer, "mod st, %s, %x", st_mod[(op >> 5) & 0xf], op & 0xf);
+ break;
+
+ //????????????????????
+
+ case 0x00:
+
+ if(op == 0) // right?
+ {
+ // nop
+ sprintf(buffer, "nop");
+ }
+ else if((op & 0xff) == 0x65)
+ {
+ // ret
+ sprintf(buffer, "ret");
+ }
+ else
+ {
+ // ld d, s
+ sprintf(buffer, "ld %s, %s", reg[(op >> 4) & 0xf], reg[0xf]);
+ }
+
+ break;
+
+ // ld d, (ri) -> probably right
+ case 0x01: // or ldi simm ?
+ sprintf(buffer, "ld %s, (%s%s)", reg[(op >> 4) & 0xf], RIJ, MODIFIER_LOW);
+ break;
+
+ // ld (ri), s
+ case 0x02:
+ sprintf(buffer, "ld (%s%s), %s", RIJ, MODIFIER_LOW, reg[(op >> 4) & 0xf]);
+ break;
+
+ // ld a, addr
+ case 0x03:
+ sprintf(buffer, "ld a, %X", op & 0x1ff);
+ break;
+
+ // ldi d, imm
+ case 0x04:
+ sprintf(buffer, "ld %s, %X", reg[(op >> 4) & 0xf], READ_OP_DASM(pc+2));
+ size = 2;
+ break;
+
+ // ld d, ((ri))
+ case 0x05:
+ sprintf(buffer, "ld %s, ((%s%s))", reg[(op >> 4) & 0xf], RIJ, MODIFIER_LOW);
+ break;
+
+ // ldi (ri), imm
+ case 0x06:
+ sprintf(buffer, "ld (%s%s), %X", RIJ, MODIFIER_LOW, READ_OP_DASM(pc+2));
+ size = 2;
+ break;
+
+ // ld addr, a -> almost sure it's this one. some of the 1st 4 bits are set in the code
+ case 0x07: // or ld d, (a) ?
+ sprintf(buffer, "ld %X, a", op & 0x1ff);
+ break;
+
+ // ld d, ri
+ case 0x09:
+ sprintf(buffer, "ld %s, %s%s", reg[(op >> 4) & 0xf], RIJ, MODIFIER_LOW);
+ break;
+
+ // ld ri, s
+ case 0x0a:
+ sprintf(buffer, "ld %s%s, %s", RIJ, MODIFIER_LOW, reg[(op >> 4) & 0xf]);
+ break;
+
+ // mpys (rj), (ri), b
+ case 0x0b:
+ sprintf(buffer, "mpya (%s%s), (%s%s), %d", RJ(op >> 4), MODIFIER_HIGH, RI(op), MODIFIER_LOW, BIT_B);
+ break;
+
+ // ldi ri, simm
+ case 0x0c:
+ case 0x0d:
+ case 0x0e:
+ case 0x0f:
+ sprintf(buffer, "ldi %s, %X", rij[(op >> 7) & 7], op & 0xff);
+ break;
+
+ // sub a, s
+ case 0x10:
+ sprintf(buffer, "sub a, %s", reg[op & 0xf]);
+ break;
+
+ // sub a, (ri)
+ case 0x11:
+ sprintf(buffer, "sub a, (%s%s)", RIJ, MODIFIER_LOW);
+ break;
+
+ // mpys s, (ri), b
+ case 0x12:
+ sprintf(buffer, "mpya %s, (%s%s), %d", reg[(op >> 4) & 0xf], RI(op), MODIFIER_LOW, BIT_B);
+ break;
+
+ // sub a, adr
+ case 0x13:
+ sprintf(buffer, "sub a, %X", op & 0xff);
+ break;
+
+ // subi a, imm
+ case 0x14:
+ sprintf(buffer, "subi a, %X", READ_OP_DASM(pc+2));
+ size = 2;
+ break;
+
+ // sub a, ((ri))
+ case 0x15:
+ sprintf(buffer, "sub a, ((%s%s))", RIJ, MODIFIER_LOW);
+ break;
+
+ // sub a, ri
+ case 0x19:
+ sprintf(buffer, "sub a, %s%s", RIJ, MODIFIER_LOW);
+ break;
+
+ // mset reg, (ri), s
+ case 0x1a:
+ case 0x1b:
+ sprintf(buffer, "mset %s, (%s%s), %d", reg[(op >> 5) & 0x1f], RI(op), MODIFIER_LOW, (op >> 4) & 1);
+ break;
+
+ // subi simm
+ case 0x1c:
+ sprintf(buffer, "subi %X", op & 0xff);
+ break;
+
+ // sub a, erij
+ case 0x23:
+ sprintf(buffer, "sub a, %s%s", erij[(op >> 2) & 7], MODIFIER(op));
+ break;
+
+ // call cond, addr
+ case 0x24: //f bit?
+ sprintf(buffer, "call %s, %X", COND, READ_OP_DASM(pc+2));
+ size = 2;
+ break;
+
+ // bra cond, addr
+ case 0x26: //f bit?
+ sprintf(buffer, "bra %s, %X", COND, READ_OP_DASM(pc+2));
+ size = 2;
+ break;
+
+
+ case 0x28:
+
+ if(op & 0x100)
+ {
+ // slow imm
+ sprintf(buffer, "slow %X", op & 0xf);
+ }
+ else
+ {
+ // stop
+ sprintf(buffer, "stop");
+ }
+
+ break;
+
+ // cmp a, s
+ case 0x30:
+ sprintf(buffer, "cmp a, %s", reg[op & 0xf]);
+ break;
+
+ // cmp a, (ri)
+ case 0x31:
+ sprintf(buffer, "cmp a, (%s%s)", RIJ, MODIFIER_LOW);
+ break;
+
+ // cmp a, adr
+ case 0x33:
+ sprintf(buffer, "cmp a, %X", op & 0xff);
+ break;
+
+ // cmpi a, imm
+ case 0x34:
+ sprintf(buffer, "cmpi a, %X", READ_OP_DASM(pc+2));
+ size = 2;
+ break;
+
+ // cmp a, ((ri))
+ case 0x35:
+ sprintf(buffer, "cmp a, ((%s%s))", RIJ, MODIFIER_LOW);
+ break;
+
+ // cmp a, ri
+ case 0x39:
+ sprintf(buffer, "cmp a, %s%s", RIJ, MODIFIER_LOW);
+ break;
+
+ // cmpi simm
+ case 0x3c:
+ sprintf(buffer, "cmpi %X", op & 0xff);
+ break;
+
+ // add a, s
+ case 0x40:
+ sprintf(buffer, "add a, %s", reg[op & 0xf]);
+ break;
+
+ // add a, (ri)
+ case 0x41:
+ sprintf(buffer, "add a, (%s%s)", RIJ, MODIFIER_LOW);
+ break;
+
+ // mpya s, (ri), b
+ case 0x42:
+ sprintf(buffer, "mpya %s, (%s%s), %d", reg[(op >> 4) & 0xf], RI(op), MODIFIER_LOW, BIT_B);
+ break;
+
+ // add a, adr
+ case 0x43:
+ sprintf(buffer, "add a, %X", op & 0xff);
+ break;
+
+ // addi a, imm
+ case 0x44:
+ //sprintf(buffer, "addi a, %X", READ_OP_DASM(pc+2));
+ size = 2;
+
+ if(op & 0x1ff)
+ sprintf(buffer, "addi a, %X (CHECK ME!)", READ_OP_DASM(pc+2));
+ else
+ sprintf(buffer, "addi a, %X", READ_OP_DASM(pc+2));
+
+ break;
+
+ // add a, ((ri))
+ case 0x45:
+ sprintf(buffer, "add a, ((%s%s))", RIJ, MODIFIER_LOW);
+ break;
+
+ // mod cond, op
+ case 0x48:
+ sprintf(buffer, "mod %s, %s", COND, acc_op[op & 7]);
+ break;
+
+ // add a, ri
+ case 0x49:
+ sprintf(buffer, "add a, %s%s", RIJ, MODIFIER_LOW);
+ break;
+
+ // mod f, op
+ case 0x4a:
+ sprintf(buffer, "%s", flag_op[op & 0xf]);
+ break;
+
+ // mpya (rj), (ri), b
+ case 0x4b:
+ sprintf(buffer, "mpya (%s%s), (%s%s), %d", RJ(op >> 4), MODIFIER_HIGH, RI(op), MODIFIER_LOW, BIT_B);
+ break;
+
+ // addi simm
+ case 0x4c: // docs show a wrong opcode value
+ sprintf(buffer, "addi %X", op & 0xff);
+ break;
+
+ // ld reg, erij
+ case 0x4e:
+ case 0x4f:
+ sprintf(buffer, "ld %s, %s%s", reg[(op >> 5) & 0x1f], erij[(op >> 2) & 7], MODIFIER(op));
+ break;
+
+ // and a, s
+ case 0x50:
+ sprintf(buffer, "and a, %s", reg[op & 0xf]);
+ break;
+
+ // and a, (ri)
+ case 0x51:
+ sprintf(buffer, "and a, (%s%s)", RIJ, MODIFIER_LOW);
+ break;
+
+ // mld s, (ri), b
+ case 0x52:
+ sprintf(buffer, "mld %s, (%s%s), %d", reg[(op >> 4) & 0xf], RI(op), MODIFIER_LOW, BIT_B);
+ break;
+
+ // and a, adr
+ case 0x53:
+ sprintf(buffer, "and a, %X", op & 0xff);
+ break;
+
+ // andi a, imm
+ case 0x54:
+// sprintf(buffer, "andi a, %X", READ_OP_DASM(pc+2));
+ size = 2;
+
+ if(op & 0x1ff)
+ sprintf(buffer, "andi a, %X (CHECK ME!)", READ_OP_DASM(pc+2));
+ else
+ sprintf(buffer, "andi a, %X", READ_OP_DASM(pc+2));
+
+ break;
+
+ // and a, ((ri))
+ case 0x55:
+ sprintf(buffer, "and a, ((%s%s))", RIJ, MODIFIER_LOW);
+ break;
+
+ // and a, ri
+ case 0x59:
+ sprintf(buffer, "and a, %s%s", RIJ, MODIFIER_LOW);
+ break;
+
+ // mld (rj), (ri), b
+ case 0x5b:
+ sprintf(buffer, "mld (%s%s), (%s%s), %d", RJ(op >> 4), MODIFIER_HIGH, RI(op), MODIFIER_LOW, BIT_B);
+ break;
+
+ // andi simm
+ case 0x5c:
+ sprintf(buffer, "andi %X", op & 0xff);
+ break;
+
+ // ld erij, reg
+ case 0x5e:
+ case 0x5f:
+ sprintf(buffer, "ld %s%s, %s", erij[(op >> 2) & 7], MODIFIER(op), reg[(op >> 5) & 0x1f]);
+ break;
+
+ // or a, s
+ case 0x60:
+ sprintf(buffer, "or a, %s", reg[op & 0xf]);
+ break;
+
+ // or a, (ri)
+ case 0x61:
+ sprintf(buffer, "or a, (%s%s)", RIJ, MODIFIER_LOW);
+ break;
+
+ // or a, adr
+ case 0x63:
+ sprintf(buffer, "or a, %X", op & 0xff);
+ break;
+
+ // ori a, imm
+ case 0x64:
+ sprintf(buffer, "ori a, %X", READ_OP_DASM(pc+2));
+ size = 2;
+ break;
+
+ // or a, ((ri))
+ case 0x65:
+ sprintf(buffer, "or a, ((%s%s))", RIJ, MODIFIER_LOW);
+ break;
+
+ // or a, ri
+ case 0x69:
+ sprintf(buffer, "or a, %s%s", RIJ, MODIFIER_LOW);
+ break;
+
+ // ori simm
+ case 0x6c:
+ sprintf(buffer, "ori %X", op & 0xff);
+ break;
+
+ // eor a, s
+ case 0x70:
+ sprintf(buffer, "eor a, %s", reg[op & 0xf]);
+ break;
+
+ // eor a, (ri)
+ case 0x71:
+ sprintf(buffer, "eor a, (%s%s)", RIJ, MODIFIER_LOW);
+ break;
+
+ // eor a, adr
+ case 0x73:
+ sprintf(buffer, "eor a, %X", op & 0xff);
+ break;
+
+ // eori a, imm
+ case 0x74:
+ sprintf(buffer, "eori a, %X", READ_OP_DASM(pc+2));
+ size = 2;
+ break;
+
+ // eor a, ((ri))
+ case 0x75:
+ sprintf(buffer, "eor a, ((%s%s))", RIJ, MODIFIER_LOW);
+ break;
+
+ // eor a, ri
+ case 0x79:
+ sprintf(buffer, "eor a, %s%s", RIJ, MODIFIER_LOW);
+ break;
+
+ // eori simm
+ case 0x7c:
+ sprintf(buffer, "eori %X", op & 0xff);
+ break;
+
+ default:
+ sprintf(buffer, "OP = %02X",op_num);
+ break;
+ }
+
+ return size | flags | DASMFLAG_SUPPORTED;
+}