The dsp561xx CPU core now generates accurate disassembly for Konami Polygonet hardware

(verified against Motorola's reference disassembler). [Andrew Gardner, Stiletto]
This commit is contained in:
Andrew Gardner 2010-08-04 05:11:00 +00:00
parent 9cebbc0639
commit 7543a1a9a4
13 changed files with 5782 additions and 3266 deletions

8
.gitattributes vendored
View File

@ -94,6 +94,14 @@ src/emu/cpu/dsp56k/dsp56k.h svneol=native#text/plain
src/emu/cpu/dsp56k/dsp56mem.c svneol=native#text/plain src/emu/cpu/dsp56k/dsp56mem.c svneol=native#text/plain
src/emu/cpu/dsp56k/dsp56ops.c svneol=native#text/plain src/emu/cpu/dsp56k/dsp56ops.c svneol=native#text/plain
src/emu/cpu/dsp56k/dsp56pcu.c svneol=native#text/plain src/emu/cpu/dsp56k/dsp56pcu.c svneol=native#text/plain
src/emu/cpu/dsp56k/inst.c svneol=native#text/plain
src/emu/cpu/dsp56k/inst.h svneol=native#text/plain
src/emu/cpu/dsp56k/opcode.c svneol=native#text/plain
src/emu/cpu/dsp56k/opcode.h svneol=native#text/plain
src/emu/cpu/dsp56k/pmove.c svneol=native#text/plain
src/emu/cpu/dsp56k/pmove.h svneol=native#text/plain
src/emu/cpu/dsp56k/tables.c svneol=native#text/plain
src/emu/cpu/dsp56k/tables.h svneol=native#text/plain
src/emu/cpu/e132xs/32xsdasm.c svneol=native#text/plain src/emu/cpu/e132xs/32xsdasm.c svneol=native#text/plain
src/emu/cpu/e132xs/e132xs.c svneol=native#text/plain src/emu/cpu/e132xs/e132xs.c svneol=native#text/plain
src/emu/cpu/e132xs/e132xs.h svneol=native#text/plain src/emu/cpu/e132xs/e132xs.h svneol=native#text/plain

View File

@ -1054,14 +1054,30 @@ ifneq ($(filter DSP56156,$(CPUS)),)
OBJDIRS += $(CPUOBJ)/dsp56k OBJDIRS += $(CPUOBJ)/dsp56k
CPUOBJS += $(CPUOBJ)/dsp56k/dsp56k.o CPUOBJS += $(CPUOBJ)/dsp56k/dsp56k.o
DASMOBJS += $(CPUOBJ)/dsp56k/dsp56dsm.o DASMOBJS += $(CPUOBJ)/dsp56k/dsp56dsm.o
DASMOBJS += $(CPUOBJ)/dsp56k/opcode.o
DASMOBJS += $(CPUOBJ)/dsp56k/inst.o
DASMOBJS += $(CPUOBJ)/dsp56k/pmove.o
DASMOBJS += $(CPUOBJ)/dsp56k/tables.o
endif endif
$(CPUOBJ)/dsp56k/dsp56k.o: $(CPUSRC)/dsp56k/dsp56k.c \ $(CPUOBJ)/dsp56k/dsp56k.o: $(CPUSRC)/dsp56k/dsp56k.c \
$(CPUSRC)/dsp56k/opcode.c \
$(CPUSRC)/dsp56k/inst.c \
$(CPUSRC)/dsp56k/pmove.c \
$(CPUSRC)/dsp56k/tables.c \
$(CPUSRC)/dsp56k/dsp56ops.c \ $(CPUSRC)/dsp56k/dsp56ops.c \
$(CPUSRC)/dsp56k/dsp56mem.c \ $(CPUSRC)/dsp56k/dsp56mem.c \
$(CPUSRC)/dsp56k/dsp56pcu.c \ $(CPUSRC)/dsp56k/dsp56pcu.c \
$(CPUSRC)/dsp56k/dsp56k.h $(CPUSRC)/dsp56k/dsp56k.h
$(CPUOBJ)/dsp56k/dsp56dsm.o: $(CPUSRC)/dsp56k/opcode.c \
$(CPUSRC)/dsp56k/opcode.h \
$(CPUSRC)/dsp56k/inst.c \
$(CPUSRC)/dsp56k/inst.h \
$(CPUSRC)/dsp56k/pmove.c \
$(CPUSRC)/dsp56k/pmove.h \
$(CPUSRC)/dsp56k/tables.c \
$(CPUSRC)/dsp56k/tables.h
#------------------------------------------------- #-------------------------------------------------

File diff suppressed because it is too large Load Diff

783
src/emu/cpu/dsp56k/inst.c Normal file
View File

@ -0,0 +1,783 @@
#include "inst.h"
#include "emu.h"
namespace DSP56K
{
// Factory
Instruction* Instruction::decodeInstruction(const Opcode* opc,
const UINT16 word0,
const UINT16 word1,
bool shifted)
{
UINT16 w0 = word0;
UINT16 w1 = word1;
if (shifted)
{
w0 = w1;
w1 = 0x0000;
}
/**************************************************************************/
/* The very funky case of the XMemoryDataMoveWithShortDisplacement */
/**************************************************************************/
if ((w0 & 0xff00) == 0x0500)
{
// Avoid "05-- 05--" recursion
if (shifted) return NULL;
Instruction* op = decodeInstruction(opc, w0, w1, true);
if (op)
{
// This parallel move only works for certain trailing instructions.
if (dynamic_cast<Add*>(op) ||
dynamic_cast<Asr*>(op) ||
dynamic_cast<Eor*>(op) ||
dynamic_cast<Mac*>(op) ||
dynamic_cast<Macr*>(op) ||
dynamic_cast<Mpy*>(op) ||
dynamic_cast<Neg*>(op) ||
dynamic_cast<Sub*>(op) ||
dynamic_cast<Tfr*>(op) ||
dynamic_cast<Tst*>(op))
{
op->m_sizeIncrement = 1;
return op;
}
}
global_free(op);
//return NULL;
}
/**************************************************************************/
/* Dual X Memory Data Read : 011m mKKK .rr. .... : A-142 */
/* Quote: (MOVE, MAC(R), MPY(R), ADD, SUB, TFR) */
/**************************************************************************/
/* TFR : 011m mKKK 0rr1 F0DD : A-212 */
if ((w0 & 0xe094) == 0x6010)
{
return global_alloc(Tfr_2(opc, w0, w1));
}
/* MOVE : 011m mKKK 0rr1 0000 : A-128 */
if ((w0 & 0xe097) == 0x6017)
{
return global_alloc(Move_2(opc, w0, w1));
}
/* MAC : 011m mKKK 1xx0 F1QQ : A-122 */
else if ((w0 & 0xe094) == 0x6084)
{
return global_alloc(Mac_3(opc, w0, w1));
}
/* MACR: 011m mKKK 1--1 F1QQ : A-124 */
else if ((w0 & 0xe094) == 0x6094)
{
return global_alloc(Macr_2(opc, w0, w1));
}
/* MPY : 011m mKKK 1xx0 F0QQ : A-160 */
else if ((w0 & 0xe094) == 0x6080)
{
return global_alloc(Mpy_2(opc, w0, w1));
}
/* MPYR : 011m mKKK 1--1 F0QQ : A-162 */
else if ((w0 & 0xe094) == 0x6090)
{
return global_alloc(Mpyr_2(opc, w0, w1));
}
/* ADD : 011m mKKK 0rru Fuuu : A-22 */
/* SUB : 011m mKKK 0rru Fuuu : A-202 */
else if ((w0 & 0xe080) == 0x6000)
{
return global_alloc(Add_2(opc, w0, w1));
}
/****************************************************************************/
/* X Memory Data Write and Register Data Move : 0001 011k RRDD .... : A-140 */
/* Quote: (MPY or MAC) */
/****************************************************************************/
/* MPY : 0001 0110 RRDD FQQQ : A-160 */
else if ((w0 & 0xff00) == 0x1600)
{
return global_alloc(Mpy_3(opc, w0, w1));
}
/* MAC : 0001 0111 RRDD FQQQ : A-122 */
else if ((w0 & 0xff00) == 0x1700)
{
return global_alloc(Mac_3(opc, w0, w1));
}
/****************************************************************/
/* No Parallel Data Move : 0100 1010 .... .... : A-131 */
/* Register to Register Data Move : 0100 IIII .... .... : A-133 */
/* Address Register Update : 0011 0zRR .... .... : A-135 */
/* X Memory Data Move : 1mRR HHHW .... .... : A-137 */
/* X Memory Data Move : 0101 HHHW .... .... : A-137 */
/* Quote: (32 General parallel move instructions) */
/****************************************************************/
else if (((w0 & 0xff00) == 0x4a00) ||
((w0 & 0xf000) == 0x4000) ||
((w0 & 0xf800) == 0x3000) ||
((w0 & 0x8000) == 0x8000) ||
((w0 & 0xf000) == 0x5000))
{
/* Note: There is much overlap down here, so certain ops must come before others */
/* CLR : .... .... 0000 F001 : A-60 */
if ((w0 & 0x00f7) == 0x0001)
{
return global_alloc(Clr(opc, w0, w1));
}
/* ADD : .... .... 0000 FJJJ : A-22 */
else if ((w0 & 0x00f0) == 0x0000)
{
return global_alloc(Add(opc, w0, w1));
}
/* MOVE : .... .... 0001 0001 : A-128 */
else if ((w0 & 0x00ff) == 0x0011 || (w0 & 0x00ff) == 0x0019)
// NEW // else if ((w0 & 0x00ff) == 0x0011)
{
return global_alloc(Move(opc, w0, w1));
}
/* TFR : .... .... 0001 FJJJ : A-212 */
else if ((w0 & 0x00f0) == 0x0010)
{
return global_alloc(Tfr(opc, w0, w1));
}
/* RND : .... .... 0010 F000 : A-188 */
else if ((w0 & 0x00f7) == 0x0020)
{
return global_alloc(Rnd(opc, w0, w1));
}
/* TST : .... .... 0010 F001 : A-218 */
else if ((w0 & 0x00f7) == 0x0021)
{
return global_alloc(Tst(opc, w0, w1));
}
/* INC : .... .... 0010 F010 : A-104 */
else if ((w0 & 0x00f7) == 0x0022)
{
return global_alloc(Inc(opc, w0, w1));
}
/* INC24 : .... .... 0010 F011 : A-106 */
else if ((w0 & 0x00f7) == 0x0023)
{
return global_alloc(Inc24(opc, w0, w1));
}
/* OR : .... .... 0010 F1JJ : A-176 */
else if ((w0 & 0x00f4) == 0x0024)
{
return global_alloc(Or(opc, w0, w1));
}
/* ASR : .... .... 0011 F000 : A-32 */
else if ((w0 & 0x00f7) == 0x0030)
{
return global_alloc(Asr(opc, w0, w1));
}
/* ASL : .... .... 0011 F001 : A-28 */
else if ((w0 & 0x00f7) == 0x0031)
{
return global_alloc(Asl(opc, w0, w1));
}
/* LSR : .... .... 0011 F010 : A-120 */
else if ((w0 & 0x00f7) == 0x0032)
{
return global_alloc(Lsr(opc, w0, w1));
}
/* LSL : .... .... 0011 F011 : A-118 */
else if ((w0 & 0x00f7) == 0x0033)
{
return global_alloc(Lsl(opc, w0, w1));
}
/* EOR : .... .... 0011 F1JJ : A-94 */
else if ((w0 & 0x00f4) == 0x0034)
{
return global_alloc(Eor(opc, w0, w1));
}
/* SUBL : .... .... 0100 F001 : A-204 */
else if ((w0 & 0x00f7) == 0x0041)
{
return global_alloc(Subl(opc, w0, w1));
}
/* SUB : .... .... 0100 FJJJ : A-202 */
else if ((w0 & 0x00f0) == 0x0040)
{
return global_alloc(Sub(opc, w0, w1));
}
/* CLR24 : .... .... 0101 F001 : A-62 */
else if ((w0 & 0x00f7) == 0x0051)
{
return global_alloc(Clr24(opc, w0, w1));
}
/* SBC : .... .... 0101 F01J : A-198 */
else if ((w0 & 0x00f6) == 0x0052)
{
return global_alloc(Sbc(opc, w0, w1));
}
/* CMP : .... .... 0101 FJJJ : A-64 */
else if ((w0 & 0x00f0) == 0x0050)
{
return global_alloc(Cmp(opc, w0, w1));
}
/* NEG : .... .... 0110 F000 : A-166 */
else if ((w0 & 0x00f7) == 0x0060)
{
return global_alloc(Neg(opc, w0, w1));
}
/* NOT : .... .... 0110 F001 : A-174 */
else if ((w0 & 0x00f7) == 0x0061)
{
return global_alloc(Not(opc, w0, w1));
}
/* DEC : .... .... 0110 F010 : A-72 */
else if ((w0 & 0x00f7) == 0x0062)
{
return global_alloc(Dec(opc, w0, w1));
}
/* DEC24 : .... .... 0110 F011 : A-74 */
else if ((w0 & 0x00f7) == 0x0063)
{
return global_alloc(Dec24(opc, w0, w1));
}
/* AND : .... .... 0110 F1JJ : A-24 */
else if ((w0 & 0x00f4) == 0x0064)
{
return global_alloc(And(opc, w0, w1));
}
/* ABS : .... .... 0111 F001 : A-18 */
if ((w0 & 0x00f7) == 0x0071)
{
return global_alloc(Abs(opc, w0, w1));
}
/* ROR : .... .... 0111 F010 : A-192 */
else if ((w0 & 0x00f7) == 0x0072)
{
return global_alloc(Ror(opc, w0, w1));
}
/* ROL : .... .... 0111 F011 : A-190 */
else if ((w0 & 0x00f7) == 0x0073)
{
return global_alloc(Rol(opc, w0, w1));
}
/* CMPM : .... .... 0111 FJJJ : A-66 */
else if ((w0 & 0x00f0) == 0x0070)
{
return global_alloc(Cmpm(opc, w0, w1));
}
/* MPY : .... .... 1k00 FQQQ : A-160 */
else if ((w0 & 0x00b0) == 0x0080)
{
return global_alloc(Mpy(opc, w0, w1));
}
/* MPYR : .... .... 1k01 FQQQ : A-162 */
else if ((w0 & 0x00b0) == 0x0090)
{
return global_alloc(Mpyr(opc, w0, w1));
}
/* MAC : .... .... 1k10 FQQQ : A-122 */
else if ((w0 & 0x00b0) == 0x00a0)
{
return global_alloc(Mac(opc, w0, w1));
}
/* MACR : .... .... 1k11 FQQQ : A-124 */
else if ((w0 & 0x00b0) == 0x00b0)
{
return global_alloc(Macr(opc, w0, w1));
}
}
/******************************/
/* Remaining non-parallel ops */
/******************************/
/* ADC : 0001 0101 0000 F01J : A-20 */
else if ((w0 & 0xfff6) == 0x1502)
{
return global_alloc(Adc(opc, w0, w1));
}
/* ANDI : 0001 1EE0 iiii iiii : A-26 */
/* Note: MoveP sneaks in here if you don't check 0x0600 */
else if (((w0 & 0xf900) == 0x1800) & ((w0 & 0x0600) != 0x0000))
{
return global_alloc(Andi(opc, w0, w1));
}
/* ASL4 : 0001 0101 0011 F001 : A-30 */
else if ((w0 & 0xfff7) == 0x1531)
{
return global_alloc(Asl4(opc, w0, w1));
}
/* ASR4 : 0001 0101 0011 F000 : A-34 */
else if ((w0 & 0xfff7) == 0x1530)
{
return global_alloc(Asr4(opc, w0, w1));
}
/* ASR16 : 0001 0101 0111 F000 : A-36 */
else if ((w0 & 0xfff7) == 0x1570)
{
return global_alloc(Asr16(opc, w0, w1));
}
/* BFCHG : 0001 0100 11Pp pppp BBB1 0010 iiii iiii : A-38 */
else if (((w0 & 0xffc0) == 0x14c0) && ((w1 & 0x1f00) == 0x1200))
{
return global_alloc(BfInstruction(opc, w0, w1));
}
/* BFCHG : 0001 0100 101- --RR BBB1 0010 iiii iiii : A-38 */
else if (((w0 & 0xfff0) == 0x14b0) && ((w1 & 0x1f00) == 0x1200))
// NEW // else if (((w0 & 0xffe0) == 0x14a0) && ((w1 & 0x1f00) == 0x1200))
{
return global_alloc(BfInstruction(opc, w0, w1));
}
/* BFCHG : 0001 0100 100D DDDD BBB1 0010 iiii iiii : A-38 */
else if (((w0 & 0xffe0) == 0x1480) && ((w1 & 0x1f00) == 0x1200))
{
return global_alloc(BfInstruction(opc, w0, w1));
}
/* BFCLR : 0001 0100 11Pp pppp BBB0 0100 iiii iiii : A-40 */
else if (((w0 & 0xffc0) == 0x14c0) && ((w1 & 0x1f00) == 0x0400))
{
return global_alloc(BfInstruction(opc, w0, w1));
}
/* BFCLR : 0001 0100 101- --RR BBB0 0100 iiii iiii : A-40 */
else if (((w0 & 0xfff0) == 0x14b0) && ((w1 & 0x1f00) == 0x0400))
// NEW // else if (((w0 & 0xffe0) == 0x14a0) && ((w1 & 0x1f00) == 0x0400))
{
return global_alloc(BfInstruction(opc, w0, w1));
}
/* BFCLR : 0001 0100 100D DDDD BBB0 0100 iiii iiii : A-40 */
else if (((w0 & 0xffe0) == 0x1480) && ((w1 & 0x1f00) == 0x0400))
{
return global_alloc(BfInstruction(opc, w0, w1));
}
/* BFSET : 0001 0100 11Pp pppp BBB1 1000 iiii iiii : A-42 */
else if (((w0 & 0xffc0) == 0x14c0) && ((w1 & 0x1f00) == 0x1800))
{
return global_alloc(BfInstruction(opc, w0, w1));
}
/* BFSET : 0001 0100 101- --RR BBB1 1000 iiii iiii : A-42 */
else if (((w0 & 0xfff0) == 0x14b0) && ((w1 & 0x1f00) == 0x1800))
// NEW // else if (((w0 & 0xffe0) == 0x14a0) && ((w1 & 0x1f00) == 0x1800))
{
return global_alloc(BfInstruction(opc, w0, w1));
}
/* BFSET : 0001 0100 100D DDDD BBB1 1000 iiii iiii : A-42 */
else if (((w0 & 0xffe0) == 0x1480) && ((w1 & 0x1f00) == 0x1800))
{
return global_alloc(BfInstruction(opc, w0, w1));
}
/* BFTSTH : 0001 0100 01Pp pppp BBB1 0000 iiii iiii : A-44 */
else if (((w0 & 0xffc0) == 0x1440) && ((w1 & 0x1f00) == 0x1000))
{
return global_alloc(BfInstruction(opc, w0, w1));
}
/* BFTSTH : 0001 0100 001- --RR BBB1 0000 iiii iiii : A-44 */
else if (((w0 & 0xfff0) == 0x1430) && ((w1 & 0x1f00) == 0x1000))
// NEW // else if (((w0 & 0xffe0) == 0x1420) && ((w1 & 0x1f00) == 0x1000))
{
return global_alloc(BfInstruction(opc, w0, w1));
}
/* BFTSTH : 0001 0100 000D DDDD BBB1 0000 iiii iiii : A-44 */
else if (((w0 & 0xffe0) == 0x1400) && ((w1 & 0x1f00) == 0x1000))
{
return global_alloc(BfInstruction(opc, w0, w1));
}
/* BFTSTL : 0001 0100 01Pp pppp BBB0 0000 iiii iiii : A-46 */
else if (((w0 & 0xffc0) == 0x1440) && ((w1 & 0x1f00) == 0x0000))
{
return global_alloc(BfInstruction(opc, w0, w1));
}
/* BFTSTL : 0001 0100 001- --RR BBB0 0000 iiii iiii : A-46 */
else if (((w0 & 0xfff0) == 0x1430) && ((w1 & 0x1f00) == 0x0000))
// NEW // else if (((w0 & 0xffe0) == 0x1420) && ((w1 & 0x1f00) == 0x0000))
{
return global_alloc(BfInstruction(opc, w0, w1));
}
/* BFTSTL : 0001 0100 000D DDDD BBB0 0000 iiii iiii : A-46 */
else if (((w0 & 0xffe0) == 0x1400) && ((w1 & 0x1f00) == 0x0000))
{
return global_alloc(BfInstruction(opc, w0, w1));
}
/* Bcc : 0000 0111 --11 cccc xxxx xxxx xxxx xxxx : A-48 */
else if (((w0 & 0xff30) == 0x0730) && ((w1 & 0x0000) == 0x0000))
{
return global_alloc(Bcc(opc, w0, w1));
}
/* Bcc : 0010 11cc ccee eeee : A-48 */
else if ((w0 & 0xfc00) == 0x2c00)
{
return global_alloc(Bcc_2(opc, w0, w1));
}
/* Bcc : 0000 0111 RR10 cccc : A-48 */
else if ((w0 & 0xff30) == 0x0720)
{
return global_alloc(Bcc_3(opc, w0, w1));
}
/* BRA : 0000 0001 0011 11-- xxxx xxxx xxxx xxxx : A-50 */
else if (((w0 & 0xfffc) == 0x013c) && ((w1 & 0x0000) == 0x0000))
{
return global_alloc(Bra(opc, w0, w1));
}
/* BRA : 0000 1011 aaaa aaaa : A-50 */
else if ((w0 & 0xff00) == 0x0b00)
{
return global_alloc(Bra_2(opc, w0, w1));
}
/* BRA : 0000 0001 0010 11RR : A-50 */
else if ((w0 & 0xfffc) == 0x012c)
{
return global_alloc(Bra_3(opc, w0, w1));
}
/* BRKc : 0000 0001 0001 cccc : A-52 */
else if ((w0 & 0xfff0) == 0x0110)
{
return global_alloc(Brkcc(opc, w0, w1));
}
/* BScc : 0000 0111 --01 cccc xxxx xxxx xxxx xxxx : A-54 */
else if (((w0 & 0xff30) == 0x0710) && ((w1 & 0x0000) == 0x0000))
{
return global_alloc(Bscc(opc, w0, w1));
}
/* BScc : 0000 0111 RR00 cccc : A-54 */
else if ((w0 & 0xff30) == 0x0700)
{
return global_alloc(Bscc_2(opc, w0, w1));
}
/* BSR : 0000 0001 0011 10-- xxxx xxxx xxxx xxxx : A-56 */
else if (((w0 & 0xfffc) == 0x0138) && ((w1 & 0x0000) == 0x0000))
{
return global_alloc(Bsr(opc, w0, w1));
}
/* BSR : 0000 0001 0010 10RR : A-56 */
else if ((w0 & 0xfffc) == 0x0128)
{
return global_alloc(Bsr_2(opc, w0, w1));
}
/* CHKAAU : 0000 0000 0000 0100 : A-58 */
else if ((w0 & 0xffff) == 0x0004)
{
return global_alloc(Chkaau(opc, w0, w1));
}
/* DEBUG : 0000 0000 0000 0001 : A-68 */
else if ((w0 & 0xffff) == 0x0001)
{
return global_alloc(Debug(opc, w0, w1));
}
/* DEBUGcc : 0000 0000 0101 cccc : A-70 */
else if ((w0 & 0xfff0) == 0x0050)
{
return global_alloc(Debugcc(opc, w0, w1));
}
/* DIV : 0001 0101 0--0 F1DD : A-76 */
else if ((w0 & 0xfff4) == 0x1504)
// NEW // else if ((w0 & 0xff94) == 0x1504)
{
return global_alloc(Div(opc, w0, w1));
}
/* DMAC : 0001 0101 10s1 FsQQ : A-80 */
else if ((w0 & 0xffd0) == 0x1590)
{
return global_alloc(Dmac(opc, w0, w1));
}
/* DO : 0000 0000 110- --RR xxxx xxxx xxxx xxxx : A-82 */
else if (((w0 & 0xffe0) == 0x00c0) && ((w1 & 0x0000) == 0x0000)) // Wait. Huh?
{
return global_alloc(Do(opc, w0, w1));
}
/* DO : 0000 1110 iiii iiii xxxx xxxx xxxx xxxx : A-82 */
else if (((w0 & 0xff00) == 0x0e00) && ((w1 & 0x0000) == 0x0000)) // Wait. Huh?
{
return global_alloc(Do_2(opc, w0, w1));
}
/* DO : 0000 0100 000D DDDD xxxx xxxx xxxx xxxx : A-82 */
else if (((w0 & 0xffe0) == 0x0400) && ((w1 & 0x0000) == 0x0000)) // Wait. Huh?
{
return global_alloc(Do_3(opc, w0, w1));
}
/* DO FOREVER : 0000 0000 0000 0010 xxxx xxxx xxxx xxxx : A-88 */
else if (((w0 & 0xffff) == 0x0002) && ((w1 & 0x0000) == 0x0000)) // Wait. Huh?
{
return global_alloc(DoForever(opc, w0, w1));
}
/* ENDDO : 0000 0000 0000 1001 : A-92 */
else if ((w0 & 0xffff) == 0x0009)
{
return global_alloc(Enddo(opc, w0, w1));
}
/* EXT : 0001 0101 0101 F010 : A-96 */
else if ((w0 & 0xfff7) == 0x1552)
{
return global_alloc(Ext(opc, w0, w1));
}
/* ILLEGAL : 0000 0000 0000 1111 : A-98 */
else if ((w0 & 0xffff) == 0x000f)
{
return global_alloc(Illegal(opc, w0, w1));
}
/* IMAC : 0001 0101 1010 FQQQ : A-100 */
else if ((w0 & 0xfff0) == 0x15a0)
{
return global_alloc(Imac(opc, w0, w1));
}
/* IMPY : 0001 0101 1000 FQQQ : A-102 */
else if ((w0 & 0xfff0) == 0x1580)
{
return global_alloc(Impy(opc, w0, w1));
}
/* Jcc : 0000 0110 --11 cccc xxxx xxxx xxxx xxxx : A-108 */
else if (((w0 & 0xff30) == 0x0630) && ((w1 & 0x0000) == 0x0000))
{
return global_alloc(Jcc(opc, w0, w1));
}
/* Jcc : 0000 0110 RR10 cccc : A-108 */
else if ((w0 & 0xff30) == 0x0620 )
{
return global_alloc(Jcc_2(opc, w0, w1));
}
/* JMP : 0000 0001 0011 01-- xxxx xxxx xxxx xxxx : A-110 */
else if (((w0 & 0xfffc) == 0x0134) && ((w1 & 0x0000) == 0x0000))
{
return global_alloc(Jmp(opc, w0, w1));
}
/* JMP : 0000 0001 0010 01RR : A-110 */
else if ((w0 & 0xfffc) == 0x0124)
{
return global_alloc(Jmp_2(opc, w0, w1));
}
/* JScc : 0000 0110 --01 cccc xxxx xxxx xxxx xxxx : A-112 */
else if (((w0 & 0xff30) == 0x0610) && ((w1 & 0x0000) == 0x0000))
{
return global_alloc(Jscc(opc, w0, w1));
}
/* JScc : 0000 0110 RR00 cccc : A-112 */
else if ((w0 & 0xff30) == 0x0600)
{
return global_alloc(Jscc_2(opc, w0, w1));
}
/* JSR : 0000 0001 0011 00-- xxxx xxxx xxxx xxxx : A-114 */
else if (((w0 & 0xfffc) == 0x0130) && ((w1 & 0x0000) == 0x0000))
{
return global_alloc(Jsr(opc, w0, w1));
}
/* JSR : 0000 1010 AAAA AAAA : A-114 */
else if ((w0 & 0xff00) == 0x0a00)
{
return global_alloc(Jsr_2(opc, w0, w1));
}
/* JSR : 0000 0001 0010 00RR : A-114 */
else if ((w0 & 0xfffc) == 0x0120)
{
return global_alloc(Jsr_3(opc, w0, w1));
}
/* LEA : 0000 0001 11TT MMRR : A-116 */
else if ((w0 & 0xffc0) == 0x01c0)
{
return global_alloc(Lea(opc, w0, w1));
}
/* LEA : 0000 0001 10NN MMRR : A-116 */
else if ((w0 & 0xffc0) == 0x0180)
{
return global_alloc(Lea_2(opc, w0, w1));
}
/* MAC(su,uu) : 0001 0101 1110 FsQQ : A-126 */
else if ((w0 & 0xfff0) == 0x15e0)
{
return global_alloc(Macsuuu(opc, w0, w1));
}
/* MOVE : 0000 0101 BBBB BBBB ---- HHHW 0001 0001 : A-128 */
// NEW // else if (((w0 & 0xff00) == 0x0500) && ((w1 & 0x00ff) == 0x0011))
// NEW // {
// NEW // return global_alloc(Move_3(opc, w0, w1));
// NEW // }
/* MOVE(C) : 0011 1WDD DDD0 MMRR : A-144 */
else if ((w0 & 0xf810) == 0x3800)
{
return global_alloc(Movec(opc, w0, w1));
}
/* MOVE(C) : 0011 1WDD DDD1 q0RR : A-144 */
else if ((w0 & 0xf814) == 0x3810)
{
return global_alloc(Movec_2(opc, w0, w1));
}
/* MOVE(C) : 0011 1WDD DDD1 Z11- : A-144 */
else if ((w0 & 0xf816) == 0x3816)
{
return global_alloc(Movec_3(opc, w0, w1));
}
/* MOVE(C) : 0011 1WDD DDD1 t10- xxxx xxxx xxxx xxxx : A-144 */
else if (((w0 & 0xf816) == 0x3814) && ((w1 & 0x0000) == 0x0000))
{
return global_alloc(Movec_4(opc, w0, w1));
}
/* MOVE(C) : 0010 10dd dddD DDDD : A-144 */
else if ((w0 & 0xfc00) == 0x2800)
{
return global_alloc(Movec_5(opc, w0, w1));
}
/* MOVE(C) : 0000 0101 BBBB BBBB 0011 1WDD DDD0 ---- : A-144 */
else if (((w0 & 0xff00) == 0x0500) && ((w1 & 0xf810) == 0x3800))
{
return global_alloc(Movec_6(opc, w0, w1));
}
/* MOVE(I) : 0010 00DD BBBB BBBB : A-150 */
else if ((w0 & 0xfc00) == 0x2000)
{
return global_alloc(Movei(opc, w0, w1));
}
/* MOVE(M) : 0000 001W RR0M MHHH : A-152 */
else if ((w0 & 0xfe20) == 0x0200)
{
return global_alloc(Movem(opc, w0, w1));
}
/* MOVE(M) : 0000 001W RR11 mmRR : A-152 */
else if ((w0 & 0xfe30) == 0x0230)
{
return global_alloc(Movem_2(opc, w0, w1));
}
/* MOVE(M) : 0000 0101 BBBB BBBB 0000 001W --0- -HHH : A-152 */
else if (((w0 & 0xff00) == 0x0500) && ((w1 & 0xfe20) == 0x0200))
{
return global_alloc(Movem_3(opc, w0, w1));
}
/* MOVE(P) : 0001 100W HH1p pppp : A-156 */
else if ((w0 & 0xfe20) == 0x1820)
{
return global_alloc(Movep(opc, w0, w1));
}
/* MOVE(P) : 0000 110W RRmp pppp : A-156 */
else if ((w0 & 0xfe00) == 0x0c00)
{
return global_alloc(Movep_2(opc, w0, w1));
}
/* MOVE(S) : 0001 100W HH0a aaaa : A-158 */
else if ((w0 & 0xfe20) == 0x1800)
{
return global_alloc(Moves(opc, w0, w1));
}
/* MPY(su,uu) : 0001 0101 1100 FsQQ : A-164 */
else if ((w0 & 0xfff0) == 0x15c0)
{
return global_alloc(Mpysuuu(opc, w0, w1));
}
/* NEGC : 0001 0101 0110 F000 : A-168 */
else if ((w0 & 0xfff7) == 0x1560)
{
return global_alloc(Negc(opc, w0, w1));
}
/* NOP : 0000 0000 0000 0000 : A-170 */
else if ((w0 & 0xffff) == 0x0000)
{
return global_alloc(Nop(opc, w0, w1));
}
/* NORM : 0001 0101 0010 F0RR : A-172 */
else if ((w0 & 0xfff4) == 0x1520)
{
return global_alloc(Norm(opc, w0, w1));
}
/* ORI : 0001 1EE1 iiii iiii : A-178 */
else if ((w0 & 0xf900) == 0x1900)
{
return global_alloc(Ori(opc, w0, w1));
}
/* REP : 0000 0000 111- --RR : A-180 */
else if ((w0 & 0xffe0) == 0x00e0)
{
return global_alloc(Rep(opc, w0, w1));
}
/* REP : 0000 1111 iiii iiii : A-180 */
else if ((w0 & 0xff00) == 0x0f00)
{
return global_alloc(Rep_2(opc, w0, w1));
}
/* REP : 0000 0100 001D DDDD : A-180 */
else if ((w0 & 0xffe0) == 0x0420)
{
return global_alloc(Rep_3(opc, w0, w1));
}
/* REPcc : 0000 0001 0101 cccc : A-184 */
else if ((w0 & 0xfff0) == 0x0150)
{
return global_alloc(Repcc(opc, w0, w1));
}
/* RESET : 0000 0000 0000 1000 : A-186 */
else if ((w0 & 0xffff) == 0x0008)
{
return global_alloc(Reset(opc, w0, w1));
}
/* RTI : 0000 0000 0000 0111 : A-194 */
else if ((w0 & 0xffff) == 0x0007)
{
return global_alloc(Rti(opc, w0, w1));
}
/* RTS : 0000 0000 0000 0110 : A-196 */
else if ((w0 & 0xffff) == 0x0006)
{
return global_alloc(Rts(opc, w0, w1));
}
/* STOP : 0000 0000 0000 1010 : A-200 */
else if ((w0 & 0xffff) == 0x000a)
{
return global_alloc(Stop(opc, w0, w1));
}
/* SWAP : 0001 0101 0111 F001 : A-206 */
else if ((w0 & 0xfff7) == 0x1571)
{
return global_alloc(Swap(opc, w0, w1));
}
/* SWI : 0000 0000 0000 0101 : A-208 */
else if ((w0 & 0xffff) == 0x0005)
{
return global_alloc(Swi(opc, w0, w1));
}
/* Tcc : 0001 00cc ccTT Fh0h : A-210 */
else if ((w0 & 0xfc02) == 0x1000)
{
return global_alloc(Tcc(opc, w0, w1));
}
/* TFR(2) : 0001 0101 0000 F00J : A-214 */
else if ((w0 & 0xfff6) == 0x1500)
{
return global_alloc(Tfr2(opc, w0, w1));
}
/* TFR(3) : 0010 01mW RRDD FHHH : A-216 */
else if ((w0 & 0xfc00) == 0x2400)
{
return global_alloc(Tfr3(opc, w0, w1));
}
/* TST(2) : 0001 0101 0001 -1DD : A-220 */
else if ((w0 & 0xfffc) == 0x1514)
// NEW // else if ((w0 & 0xfff4) == 0x1514)
{
return global_alloc(Tst2(opc, w0, w1));
}
/* WAIT : 0000 0000 0000 1011 : A-222 */
else if ((w0 & 0xffff) == 0x000b)
{
return global_alloc(Wait(opc, w0, w1));
}
/* ZERO : 0001 0101 0101 F000 : A-224 */
else if ((w0 & 0xfff7) == 0x1550)
{
return global_alloc(Zero(opc, w0, w1));
}
/* SHFL : 0001 0101 1101 FQQQ : !!UNDOCUMENTED!! */
else if ((w0 & 0xfff0) == 0x15d0)
{
return global_alloc(Shfl(opc, w0, w1));
}
/* SHFR : 0001 0101 1111 FQQQ : !!UNDOCUMENTED!! */
else if ((w0 & 0xfff0) == 0x15f0)
{
return global_alloc(Shfr(opc, w0, w1));
}
return NULL;
}
}

3702
src/emu/cpu/dsp56k/inst.h Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,71 @@
#include <cstdio>
#include "opcode.h"
namespace DSP56K
{
Opcode::Opcode(UINT16 w0, UINT16 w1) : m_word0(w0), m_word1(w1)
{
m_instruction = Instruction::decodeInstruction(this, w0, w1);
m_parallelMove = ParallelMove::decodeParallelMove(this, w0, w1);
}
Opcode::~Opcode()
{
global_free(m_instruction);
global_free(m_parallelMove);
}
std::string Opcode::disassemble() const
{
// Duck out early if there isn't a valid op
if (!m_instruction)
return dcString();
// Duck out if either has had an explicit error.
if (m_instruction && !m_instruction->valid())
return dcString();
if (m_parallelMove && !m_parallelMove->valid())
return dcString();
// Disassemble what you can.
std::string opString = "";
std::string pmString = "";
if (m_instruction) m_instruction->disassemble(opString);
if (m_parallelMove) m_parallelMove->disassemble(pmString);
return opString + " " + pmString;
}
void Opcode::evaluate() const
{
if (m_instruction) m_instruction->evaluate();
if (m_parallelMove) m_parallelMove->evaluate();
}
size_t Opcode::size() const
{
if (m_instruction && m_instruction->valid())
return m_instruction->size() + m_instruction->sizeIncrement();
// Opcode failed to decode, so push it past dc
return 1;
}
const std::string& Opcode::instSource() const { return m_instruction->source(); }
const std::string& Opcode::instDestination() const { return m_instruction->destination(); }
const size_t Opcode::instAccumulatorBitsModified() const { return m_instruction->accumulatorBitsModified(); }
std::string Opcode::dcString() const
{
char tempStr[1024];
sprintf(tempStr, "dc $%x", m_word0);
return std::string(tempStr);
}
}

View File

@ -0,0 +1,45 @@
#ifndef __DSP56K_OPCODE_H__
#define __DSP56K_OPCODE_H__
#include <string>
#include "emu.h"
#include "inst.h"
#include "pmove.h"
//
// An Opcode contains an instruction and a parallel move operation.
//
namespace DSP56K
{
class Instruction;
class ParallelMove;
class Opcode
{
public:
Opcode(UINT16 w0, UINT16 w1);
virtual ~Opcode();
std::string disassemble() const;
void evaluate() const;
size_t size() const;
// Peek through to the instruction
const std::string& instSource() const;
const std::string& instDestination() const;
const size_t instAccumulatorBitsModified() const;
private:
Instruction* m_instruction;
ParallelMove* m_parallelMove;
UINT16 m_word0;
UINT16 m_word1;
std::string dcString() const;
};
}
#endif

View File

@ -0,0 +1,78 @@
#include "pmove.h"
namespace DSP56K
{
const std::string& ParallelMove::opSource() const { return m_oco->instSource(); }
const std::string& ParallelMove::opDestination() const { return m_oco->instDestination(); }
const size_t ParallelMove::opAccumulatorBitsModified() const { return m_oco->instAccumulatorBitsModified(); }
ParallelMove* ParallelMove::decodeParallelMove(const Opcode* opc, const UINT16 word0, const UINT16 word1)
{
const UINT16 w0 = word0;
const UINT16 w1 = word1;
/* Dual X Memory Data Read : 011m mKKK .rr. .... : A-142*/
if ((w0 & 0xe000) == 0x6000)
{
return global_alloc(DualXMemoryDataRead(opc, w0, w1));
}
/* X Memory Data Write and Register Data Move : 0001 011k RRDD .... : A-140 */
else if ((w0 & 0xfe00) == 0x1600)
{
return global_alloc(XMemoryDataWriteAndRegisterDataMove(opc, w0, w1));
}
else
{
/* 32 General parallel move operations */
/* Note: It's important that NPDM comes before RtRDM */
/* No Parallel Data Move : 0100 1010 .... .... : A-131 */
if ((w0 & 0xff00) == 0x4a00)
{
return NULL;
}
/* Register to Register Data Move : 0100 IIII .... .... : A-133 */
else if ((w0 & 0xf000) == 0x4000)
{
return global_alloc(RegisterToRegisterDataMove(opc, w0, w1));
}
/* Address Register Update : 0011 0zRR .... .... : A-135 */
else if ((w0 & 0xf800) == 0x3000)
{
return global_alloc(AddressRegisterUpdate(opc, w0, w1));
}
/* X Memory Data Move : 1mRR HHHW .... .... : A-137 */
else if ((w0 & 0x8000) == 0x8000)
{
return global_alloc(XMemoryDataMove(opc, w0, w1));
}
/* X Memory Data Move : 0101 HHHW .... .... : A-137 */
else if ((w0 & 0xf000) == 0x5000)
{
return global_alloc(XMemoryDataMove_2(opc, w0, w1));
}
/* X Memory Data Move with short displacement : 0000 0101 BBBB BBBB ---- HHHW .... .... : A-139 */
else if ((w0 & 0xff00) == 0x0500)
{
// Now check it against all potential double-ups.
// These operations can't have an additional parallel move.
//
// MOVE(M) : 0000 0101 BBBB BBBB 0000 001W --0- -HHH : A-152
// MOVE(C) : 0000 0101 BBBB BBBB 0011 1WDD DDD0 ---- : A-144
// MOVE : 0000 0101 BBBB BBBB ---- HHHW 0001 0001 : A-128
//
if (((w1 & 0xfe20) != 0x0200) &&
((w1 & 0xf810) != 0x3800) &&
((w1 & 0x00ff) != 0x0011))
{
return global_alloc(XMemoryDataMoveWithShortDisplacement(opc, w0, w1));
}
}
}
return NULL;
}
}

339
src/emu/cpu/dsp56k/pmove.h Normal file
View File

@ -0,0 +1,339 @@
#ifndef __DSP56K_PARALLEL_MOVE_H__
#define __DSP56K_PARALLEL_MOVE_H__
#include <string>
#include "emu.h"
#include "opcode.h"
#include "tables.h"
//
// A ParallelMove Object is what all parallel move classes inherit from.
//
namespace DSP56K
{
class Opcode;
class ParallelMove
{
public:
ParallelMove(const Opcode* oco) : m_valid(false), m_oco(oco) { }
virtual ~ParallelMove() {}
virtual bool decode(const UINT16 word0, const UINT16 word1) = 0;
virtual void disassemble(std::string& retString) const = 0;
virtual void evaluate() = 0;
static ParallelMove* decodeParallelMove(const Opcode* opc, const UINT16 word0, const UINT16 word1);
const bool valid() const { return m_valid; }
// Peek through the opcode to see the instruction
const std::string& opSource() const;
const std::string& opDestination() const;
const size_t opAccumulatorBitsModified() const;
protected:
bool m_valid;
const Opcode* m_oco;
};
////////////////////////////////////////////////////////////////////////////////
// PARALLEL MOVES ////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/* X Memory Data Move : 1mRR HHHW .... .... : A-137 */
class XMemoryDataMove: public ParallelMove
{
public:
XMemoryDataMove(const Opcode* oco, const UINT16 word0, const UINT16 word1) : ParallelMove(oco)
{
m_valid = decode(word0, word1);
}
bool decode(const UINT16 word0, const UINT16 word1)
{
INT8 rNum;
decode_RR_table(BITSn(word0,0x3000), rNum);
std::string SD;
decode_HHH_table(BITSn(word0,0x0e00), SD);
std::string ea;
assemble_ea_from_m_table(BITSn(word0,0x4000), rNum, ea);
assemble_arguments_from_W_table(BITSn(word0,0x0100), 'X', SD, ea,
m_source, m_destination);
// If the destination of the instruction overlaps with our destination, abort.
if (registerOverlap(opDestination(), opAccumulatorBitsModified(), m_destination))
return false;
return true;
}
void disassemble(std::string& retString) const
{
retString = m_source + "," + m_destination;
}
void evaluate() {}
private:
std::string m_source;
std::string m_destination;
};
/* X Memory Data Move : 0101 HHHW .... .... : A-137 */
class XMemoryDataMove_2: public ParallelMove
{
public:
XMemoryDataMove_2(const Opcode* oco, const UINT16 word0, const UINT16 word1) : ParallelMove(oco)
{
m_valid = decode(word0, word1);
}
bool decode(const UINT16 word0, const UINT16 word1)
{
std::string ea;
if (opDestination() == "B")
ea = "(A1)";
else if (opDestination() == "A")
ea = "(B1)";
else
ea = "(A1)";
std::string SD;
decode_HHH_table(BITSn(word0,0x0e00), SD);
assemble_arguments_from_W_table(BITSn(word0,0x0100), 'X', SD, ea,
m_source, m_destination);
// If the destination of the instruction overlaps with our destination, abort.
if (registerOverlap(opDestination(), opAccumulatorBitsModified(), m_destination))
return false;
return true;
}
void disassemble(std::string& retString) const
{
retString = m_source + "," + m_destination;
}
void evaluate() {}
private:
std::string m_source;
std::string m_destination;
};
/* Dual X Memory Data Read : 011m mKKK .rr. .... : A-142*/
class DualXMemoryDataRead: public ParallelMove
{
public:
DualXMemoryDataRead(const Opcode* oco, const UINT16 word0, const UINT16 word1) : ParallelMove(oco)
{
m_valid = decode(word0, word1);
}
bool decode(const UINT16 word0, const UINT16 word1)
{
INT8 rNum;
std::string D1 = "";
std::string D2 = "";
std::string ea1 = "";
std::string ea2 = "";
decode_rr_table(BITSn(word0,0x0060), rNum);
decode_KKK_table(BITSn(word0,0x0700), D1, D2);
assemble_eas_from_mm_table(BITSn(word0,0x1800), rNum, 3, ea1, ea2);
/* Not documented, but extrapolated from docs on page A-133 */
if (D1 == "^F")
{
if (opDestination() == "B")
D1 = "A";
else if (opDestination() == "A")
D1 = "B";
else
D1 = "A"; /* In the case of no data ALU instruction */
}
/* D1 and D2 may not specify the same register : A-142 */
if (rNum == 3) return false;
char temp[32];
sprintf(temp, "X:%s,%s", ea1.c_str(), D1.c_str());
parallelMove = temp;
sprintf(temp, "X:%s,%s", ea2.c_str(), D2.c_str());
parallelMove2 = temp;
return true;
}
void disassemble(std::string& retString) const
{
retString = parallelMove + " " + parallelMove2;
}
void evaluate() {}
private:
std::string parallelMove;
std::string parallelMove2;
};
/* Register to Register Data Move : 0100 IIII .... .... : A-133 */
class RegisterToRegisterDataMove: public ParallelMove
{
public:
RegisterToRegisterDataMove(const Opcode* oco, const UINT16 word0, const UINT16 word1) : ParallelMove(oco)
{
m_valid = decode(word0, word1);
}
bool decode(const UINT16 word0, const UINT16 word1)
{
decode_IIIIx_table(BITSn(word0,0x0f00), BITSn(word0,0x0008),
m_source, m_destination);
if (m_source == "!")
return false;
if (m_source == "F")
m_source = opDestination();
if (m_destination == "^F")
{
if (opDestination() == "B")
m_destination = "A";
else if (opDestination() == "A")
m_destination = "B";
else
m_destination = "A"; /* In the case of no data ALU instruction */
}
// Don't return a failure, just let everything fall through (nop).
//if (m_source == "?" && m_destination == "?")
// return false;
return true;
}
void disassemble(std::string& retString) const
{
// (?,?) is a parallel nop
if (m_source == "?" && m_destination == "?")
retString = "";
else
retString = m_source + "," + m_destination;
}
void evaluate() {}
private:
std::string m_source;
std::string m_destination;
};
/* X Memory Data Write and Register Data Move : 0001 011k RRDD .... : A-140 */
class XMemoryDataWriteAndRegisterDataMove: public ParallelMove
{
public:
XMemoryDataWriteAndRegisterDataMove(const Opcode* oco, const UINT16 word0, const UINT16 word1) : ParallelMove(oco)
{
pms = "";
pms2 = "";
m_valid = decode(word0, word1);
}
bool decode(const UINT16 word0, const UINT16 word1)
{
INT8 rNum;
std::string S;
std::string Dnot;
char parallel_move_str[128];
char parallel_move_str2[128];
if (opDestination() == "A") Dnot = "B";
else Dnot = "A";
// NEW // decode_k_table(BITSn(word0,0x0100), Dnot);
decode_RR_table(BITSn(word0,0x00c0), rNum);
decode_DD_table(BITSn(word0,0x0030), S);
sprintf(parallel_move_str, "%s,X:(R%d)+N%d", Dnot.c_str(), rNum, rNum);
sprintf(parallel_move_str2, "%s,%s", S.c_str(), Dnot.c_str());
pms = parallel_move_str;
pms2 = parallel_move_str2;
return true;
}
void disassemble(std::string& retString) const
{
retString = pms + " " + pms2;
}
void evaluate() {}
private:
std::string pms; // TODO
std::string pms2;
};
/* Address Register Update : 0011 0zRR .... .... : A-135 */
class AddressRegisterUpdate: public ParallelMove
{
public:
AddressRegisterUpdate(const Opcode* oco, const UINT16 word0, const UINT16 word1) : ParallelMove(oco)
{
m_ea = "";
m_valid = decode(word0, word1);
}
bool decode(const UINT16 word0, const UINT16 word1)
{
INT8 rNum;
decode_RR_table(BITSn(word0,0x0300), rNum);
assemble_ea_from_z_table(BITSn(word0,0x0400), rNum, m_ea);
return true;
}
void disassemble(std::string& retString) const
{
retString = m_ea;
}
void evaluate() {}
private:
std::string m_ea;
};
/* X Memory Data Move with short displacement : 0000 0101 BBBB BBBB ---- HHHW .... .... : A-139 */
class XMemoryDataMoveWithShortDisplacement: public ParallelMove
{
public:
XMemoryDataMoveWithShortDisplacement(const Opcode* oco, const UINT16 word0, const UINT16 word1) : ParallelMove(oco)
{
m_source = "";
m_destination = "";
m_valid = decode(word0, word1);
}
bool decode(const UINT16 word0, const UINT16 word1)
{
INT8 B;
std::string SD;
std::string args;
B = (char)(word0 & 0x00ff);
decode_HHH_table(BITSn(word1,0x0e00), SD);
assemble_reg_from_W_table(BITSn(word1,0x0100), 'X', SD, B, m_source, m_destination);
return true;
}
void disassemble(std::string& retString) const
{
retString = m_source + "," + m_destination;
}
void evaluate() {}
private:
std::string m_source;
std::string m_destination;
};
}
#endif

661
src/emu/cpu/dsp56k/tables.c Normal file
View File

@ -0,0 +1,661 @@
#include <string>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include "tables.h"
namespace DSP56K
{
/******************/
/* Table decoding */
/******************/
int decode_BBB_table(UINT16 BBB)
{
switch(BBB)
{
case 0x4: return BBB_UPPER;
case 0x2: return BBB_MIDDLE;
case 0x1: return BBB_LOWER;
}
return BBB_INVALID;
}
void decode_cccc_table(const UINT16 cccc, std::string& mnemonic)
{
switch (cccc)
{
case 0x0: mnemonic = "cc"; break;
case 0x1: mnemonic = "ge"; break;
case 0x2: mnemonic = "ne"; break;
case 0x3: mnemonic = "pl"; break;
case 0x4: mnemonic = "nn"; break;
case 0x5: mnemonic = "ec"; break;
case 0x6: mnemonic = "lc"; break;
case 0x7: mnemonic = "gt"; break;
case 0x8: mnemonic = "cs"; break;
case 0x9: mnemonic = "lt"; break;
case 0xa: mnemonic = "eq"; break;
case 0xb: mnemonic = "mi"; break;
case 0xc: mnemonic = "nr"; break;
case 0xd: mnemonic = "es"; break;
case 0xe: mnemonic = "ls"; break;
case 0xf: mnemonic = "le"; break;
}
// NEW // switch (cccc)
// NEW // {
// NEW // case 0x0: sprintf(mnemonic, "cc(hs)"); break;
// NEW // case 0x1: sprintf(mnemonic, "ge "); break;
// NEW // case 0x2: sprintf(mnemonic, "ne "); break;
// NEW // case 0x3: sprintf(mnemonic, "pl "); break;
// NEW // case 0x4: sprintf(mnemonic, "nn "); break;
// NEW // case 0x5: sprintf(mnemonic, "ec "); break;
// NEW // case 0x6: sprintf(mnemonic, "lc "); break;
// NEW // case 0x7: sprintf(mnemonic, "gt "); break;
// NEW // case 0x8: sprintf(mnemonic, "cs(lo)"); break;
// NEW // case 0x9: sprintf(mnemonic, "lt "); break;
// NEW // case 0xa: sprintf(mnemonic, "eq "); break;
// NEW // case 0xb: sprintf(mnemonic, "mi "); break;
// NEW // case 0xc: sprintf(mnemonic, "nr "); break;
// NEW // case 0xd: sprintf(mnemonic, "es "); break;
// NEW // case 0xe: sprintf(mnemonic, "ls "); break;
// NEW // case 0xf: sprintf(mnemonic, "le "); break;
// NEW // }
}
void decode_DDDDD_table(const UINT16 DDDDD, std::string& SD)
{
switch(DDDDD)
{
case 0x00: SD = "X0"; break;
case 0x01: SD = "Y0"; break;
case 0x02: SD = "X1"; break;
case 0x03: SD = "Y1"; break;
case 0x04: SD = "A"; break;
case 0x05: SD = "B"; break;
case 0x06: SD = "A0"; break;
case 0x07: SD = "B0"; break;
case 0x08: SD = "LC"; break;
case 0x09: SD = "SR"; break;
case 0x0a: SD = "OMR"; break;
case 0x0b: SD = "SP"; break;
case 0x0c: SD = "A1"; break;
case 0x0d: SD = "B1"; break;
case 0x0e: SD = "A2"; break;
case 0x0f: SD = "B2"; break;
case 0x10: SD = "R0"; break;
case 0x11: SD = "R1"; break;
case 0x12: SD = "R2"; break;
case 0x13: SD = "R3"; break;
case 0x14: SD = "M0"; break;
case 0x15: SD = "M1"; break;
case 0x16: SD = "M2"; break;
case 0x17: SD = "M3"; break;
case 0x18: SD = "SSH"; break;
case 0x19: SD = "SSL"; break;
case 0x1a: SD = "LA"; break;
case 0x1b: SD = "!!"; break; /* no 0x1b */
case 0x1c: SD = "N0"; break;
case 0x1d: SD = "N1"; break;
case 0x1e: SD = "N2"; break;
case 0x1f: SD = "N3"; break;
}
}
void decode_DD_table(const UINT16 DD, std::string& SD)
{
switch (DD)
{
case 0x0: SD = "X0"; break;
case 0x1: SD = "Y0"; break;
case 0x2: SD = "X1"; break;
case 0x3: SD = "Y1"; break;
}
}
void decode_DDF_table(const UINT16 DD, const UINT16 F, std::string& S, std::string& D)
{
const UINT16 switchVal = (DD << 1) | F;
switch (switchVal)
{
case 0x0: S = "X0"; D = "A"; break;
case 0x1: S = "X0"; D = "B"; break;
case 0x2: S = "Y0"; D = "A"; break;
case 0x3: S = "Y0"; D = "B"; break;
case 0x4: S = "X1"; D = "A"; break;
case 0x5: S = "X1"; D = "B"; break;
case 0x6: S = "Y1"; D = "A"; break;
case 0x7: S = "Y1"; D = "B"; break;
}
}
void decode_EE_table(const UINT16 EE, std::string& D)
{
switch(EE)
{
case 0x1: D = "MR"; break;
case 0x3: D = "CCR"; break;
case 0x2: D = "OMR"; break;
}
}
void decode_F_table(const UINT16 F, std::string& SD)
{
switch(F)
{
case 0x0: SD = "A"; break;
case 0x1: SD = "B"; break;
}
}
void decode_h0hF_table(const UINT16 h0h, UINT16 F, std::string& S, std::string& D)
{
const UINT16 switchVal = (h0h << 1) | F;
switch (switchVal)
{
case 0x8: S = "X0"; D = "A"; break;
case 0x9: S = "X0"; D = "B"; break;
case 0xa: S = "Y0"; D = "A"; break;
case 0xb: S = "Y0"; D = "B"; break;
case 0x2: S = "A"; D = "A"; break;
case 0x1: S = "A"; D = "B"; break;
case 0x0: S = "B"; D = "A"; break;
case 0x3: S = "B"; D = "B"; break;
}
}
void decode_HH_table(const UINT16 HH, std::string& SD)
{
switch(HH)
{
case 0x0: SD = "X0"; break;
case 0x1: SD = "Y0"; break;
case 0x2: SD = "A"; break;
case 0x3: SD = "B"; break;
}
}
void decode_HHH_table(const UINT16 HHH, std::string& SD)
{
switch(HHH)
{
case 0x0: SD = "X0"; break;
case 0x1: SD = "Y0"; break;
case 0x2: SD = "X1"; break;
case 0x3: SD = "Y1"; break;
case 0x4: SD = "A"; break;
case 0x5: SD = "B"; break;
case 0x6: SD = "A0"; break;
case 0x7: SD = "B0"; break;
}
}
void decode_IIIIx_table(const UINT16 IIII, const UINT16 x, std::string& S, std::string& D)
{
S = D = "!";
switch(IIII)
{
case 0x0: S = "X0"; D = "^F"; break;
case 0x1: S = "Y0"; D = "^F"; break;
case 0x2: S = "X1"; D = "^F"; break;
case 0x3: S = "Y1"; D = "^F"; break;
case 0x4: S = "A"; D = "X0"; break;
case 0x5: S = "B"; D = "Y0"; break;
case 0x6: S = "A0"; D = "X0"; break;
case 0x7: S = "B0"; D = "Y0"; break;
case 0x8: if ( x) S = "F"; D = "^F"; break;
case 0x9: if (!x) S = "F"; D = "^F"; break;
case 0xa: S = "?"; D = "?"; break;
case 0xb: S = "?"; D = "?"; break;
case 0xc: S = "A"; D = "X1"; break;
case 0xd: S = "B"; D = "Y1"; break;
case 0xe: S = "A0"; D = "X1"; break;
case 0xf: S = "B0"; D = "Y1"; break;
}
}
void decode_JJJF_table(const UINT16 JJJ, const UINT16 F, std::string& S, std::string& D)
{
const UINT16 switchVal = (JJJ << 1) | F;
switch(switchVal)
{
case 0x0: S = "B"; D = "A"; break;
case 0x1: S = "A"; D = "B"; break;
case 0x2: S = "!"; D = "!"; break;
case 0x3: S = "!"; D = "!"; break;
case 0x4: S = "X"; D = "A"; break;
case 0x5: S = "X"; D = "B"; break;
case 0x6: S = "Y"; D = "A"; break;
case 0x7: S = "Y"; D = "B"; break;
case 0x8: S = "X0"; D = "A"; break;
case 0x9: S = "X0"; D = "B"; break;
case 0xa: S = "Y0"; D = "A"; break;
case 0xb: S = "Y0"; D = "B"; break;
case 0xc: S = "X1"; D = "A"; break;
case 0xd: S = "X1"; D = "B"; break;
case 0xe: S = "Y1"; D = "A"; break;
case 0xf: S = "Y1"; D = "B"; break;
}
}
void decode_JJF_table(const UINT16 JJ, const UINT16 F, std::string& S, std::string& D)
{
const UINT16 switchVal = (JJ << 1) | F;
switch (switchVal)
{
case 0x0: S = "X0"; D = "A"; break;
case 0x1: S = "X0"; D = "B"; break;
case 0x2: S = "Y0"; D = "A"; break;
case 0x3: S = "Y0"; D = "B"; break;
case 0x4: S = "X1"; D = "A"; break;
case 0x5: S = "X1"; D = "B"; break;
case 0x6: S = "Y1"; D = "A"; break;
case 0x7: S = "Y1"; D = "B"; break;
}
}
void decode_JF_table(const UINT16 J, const UINT16 F, std::string& S, std::string& D)
{
const UINT16 switchVal = (J << 1) | F;
switch(switchVal)
{
case 0x0: S = "X"; D = "A"; break;
case 0x1: S = "X"; D = "B"; break;
case 0x2: S = "Y"; D = "A"; break;
case 0x3: S = "Y"; D = "B"; break;
}
}
// NEW // void decode_k_table(UINT16 k, char *Dnot)
// NEW // {
// NEW // switch(k)
// NEW // {
// NEW // case 0x0: sprintf(Dnot, "B"); break;
// NEW // case 0x1: sprintf(Dnot, "A"); break;
// NEW // }
// NEW // }
void decode_kSign_table(const UINT16 k, std::string& plusMinus)
{
switch(k)
{
case 0x0: plusMinus = "+"; break;
case 0x1: plusMinus = "-"; break;
}
}
void decode_KKK_table(const UINT16 KKK, std::string& D1, std::string& D2)
{
switch(KKK)
{
case 0x0: D1 = "^F"; D2 = "X0"; break;
case 0x1: D1 = "Y0"; D2 = "X0"; break;
case 0x2: D1 = "X1"; D2 = "X0"; break;
case 0x3: D1 = "Y1"; D2 = "X0"; break;
case 0x4: D1 = "X0"; D2 = "X1"; break;
case 0x5: D1 = "Y0"; D2 = "X1"; break;
case 0x6: D1 = "^F"; D2 = "Y0"; break;
case 0x7: D1 = "Y1"; D2 = "X1"; break;
}
}
void decode_NN_table(UINT16 NN, INT8& ret)
{
ret = NN;
}
void decode_TT_table(UINT16 TT, INT8& ret)
{
ret = TT;
}
void decode_QQF_table(const UINT16 QQ, const UINT16 F, std::string& S1, std::string& S2, std::string& D)
{
const UINT16 switchVal = (QQ << 1) | F;
switch(switchVal)
{
case 0x0: S1 = "Y0"; S2 = "X0"; D = "A"; break;
case 0x1: S1 = "Y0"; S2 = "X0"; D = "B"; break;
case 0x2: S1 = "Y1"; S2 = "X0"; D = "A"; break;
case 0x3: S1 = "Y1"; S2 = "X0"; D = "B"; break;
case 0x4: S1 = "Y0"; S2 = "X1"; D = "A"; break;
case 0x5: S1 = "Y0"; S2 = "X1"; D = "B"; break;
case 0x6: S1 = "Y1"; S2 = "X1"; D = "A"; break;
case 0x7: S1 = "Y1"; S2 = "X1"; D = "B"; break;
}
}
void decode_QQF_special_table(const UINT16 QQ, const UINT16 F, std::string& S1, std::string& S2, std::string& D)
{
const UINT16 switchVal = (QQ << 1) | F;
switch(switchVal)
{
case 0x0: S1 = "Y0"; S2 = "X0"; D = "A"; break;
case 0x1: S1 = "Y0"; S2 = "X0"; D = "B"; break;
case 0x2: S1 = "Y1"; S2 = "X0"; D = "A"; break;
case 0x3: S1 = "Y1"; S2 = "X0"; D = "B"; break;
case 0x4: S1 = "X1"; S2 = "Y0"; D = "A"; break;
case 0x5: S1 = "X1"; S2 = "Y0"; D = "B"; break;
case 0x6: S1 = "X1"; S2 = "Y1"; D = "A"; break;
case 0x7: S1 = "X1"; S2 = "Y1"; D = "B"; break;
}
}
void decode_QQQF_table(const UINT16 QQQ, const UINT16 F, std::string& S1, std::string& S2, std::string& D)
{
const UINT16 switchVal = (QQQ << 1) | F;
switch(switchVal)
{
case 0x0: S1 = "X0"; S2 = "X0"; D = "A"; break;
case 0x1: S1 = "X0"; S2 = "X0"; D = "B"; break;
case 0x2: S1 = "X1"; S2 = "X0"; D = "A"; break;
case 0x3: S1 = "X1"; S2 = "X0"; D = "B"; break;
case 0x4: S1 = "A1"; S2 = "Y0"; D = "A"; break;
case 0x5: S1 = "A1"; S2 = "Y0"; D = "B"; break;
case 0x6: S1 = "B1"; S2 = "X0"; D = "A"; break;
case 0x7: S1 = "B1"; S2 = "X0"; D = "B"; break;
case 0x8: S1 = "Y0"; S2 = "X0"; D = "A"; break;
case 0x9: S1 = "Y0"; S2 = "X0"; D = "B"; break;
case 0xa: S1 = "Y1"; S2 = "X0"; D = "A"; break;
case 0xb: S1 = "Y1"; S2 = "X0"; D = "B"; break;
case 0xc: S1 = "Y0"; S2 = "X1"; D = "A"; break;
case 0xd: S1 = "Y0"; S2 = "X1"; D = "B"; break;
case 0xe: S1 = "Y1"; S2 = "X1"; D = "A"; break;
case 0xf: S1 = "Y1"; S2 = "X1"; D = "B"; break;
}
}
void decode_RR_table(UINT16 RR, INT8& ret)
{
ret = RR;
}
void decode_rr_table(UINT16 rr, INT8& ret)
{
ret = rr;
}
void decode_s_table(const UINT16 s, std::string& arithmetic)
{
switch(s)
{
case 0x0: arithmetic = "su"; break;
case 0x1: arithmetic = "uu"; break;
}
}
void decode_ss_table(const UINT16 ss, std::string& arithmetic)
{
switch(ss)
{
case 0x0: arithmetic = "ss"; break;
case 0x1: arithmetic = "!!"; break;
//case 0x1: arithmetic = "ss"; break;
case 0x2: arithmetic = "su"; break;
case 0x3: arithmetic = "uu"; break;
}
}
void decode_uuuuF_table(const UINT16 uuuu, const UINT16 F, std::string& arg, std::string& S, std::string& D)
{
const UINT16 switchVal = (uuuu << 1) | F;
D = "sub?";
S = "add";
arg = "invalid";
switch(switchVal)
{
case 0x00: arg = "add"; S = "X0"; D = "A"; break;
case 0x01: arg = "add"; S = "X0"; D = "B"; break;
case 0x02: arg = "add"; S = "Y0"; D = "A"; break;
case 0x03: arg = "add"; S = "Y0"; D = "B"; break;
case 0x04: arg = "add"; S = "X1"; D = "A"; break;
case 0x05: arg = "add"; S = "X1"; D = "B"; break;
case 0x06: arg = "add"; S = "Y1"; D = "A"; break;
case 0x07: arg = "add"; S = "Y1"; D = "B"; break;
case 0x08: arg = "sub"; S = "X0"; D = "A"; break;
case 0x09: arg = "sub"; S = "X0"; D = "B"; break;
case 0x0a: arg = "sub"; S = "Y0"; D = "A"; break;
case 0x0b: arg = "sub"; S = "Y0"; D = "B"; break;
case 0x0c: arg = "sub"; S = "X1"; D = "A"; break;
case 0x0d: arg = "sub"; S = "X1"; D = "B"; break;
case 0x0e: arg = "sub"; S = "Y1"; D = "A"; break;
case 0x0f: arg = "sub"; S = "Y1"; D = "B"; break;
case 0x18: arg = "add"; S = "B"; D = "A"; break;
case 0x19: arg = "add"; S = "A"; D = "B"; break;
case 0x1a: arg = "sub"; S = "B"; D = "A"; break;
case 0x1b: arg = "sub"; S = "A"; D = "B"; break;
case 0x1c: arg = "tfr"; S = "B"; D = "A"; break;
case 0x1d: arg = "tfr"; S = "A"; D = "B"; break;
case 0x1e: arg = "move"; S = ""; D = ""; break;
case 0x1f: arg = "move"; S = ""; D = ""; break;
}
}
void decode_Z_table(const UINT16 Z, std::string& ea)
{
/* This is fixed as per the Family Manual errata addendum */
switch(Z)
{
case 0x1: ea = "(A1)"; break;
case 0x0: ea = "(B1)"; break;
}
}
void assemble_ea_from_m_table(const UINT16 m, const int n, std::string& ea)
{
char temp[32];
switch(m)
{
case 0x0: sprintf(temp, "(R%d)+",n) ; break;
case 0x1: sprintf(temp, "(R%d)+N%d", n, n); break;
}
ea = temp;
}
void assemble_eas_from_mm_table(UINT16 mm, int n1, int n2, std::string& ea1, std::string& ea2)
{
char temp1[32];
char temp2[32];
switch(mm)
{
case 0x0: sprintf(temp1, "(R%d)+", n1) ;
sprintf(temp2, "(R%d)+", n2) ; break;
case 0x1: sprintf(temp1, "(R%d)+", n1) ;
sprintf(temp2, "(R%d)+N%d", n2, n2); break;
case 0x2: sprintf(temp1, "(R%d)+N%d", n1, n1);
sprintf(temp2, "(R%d)+", n2) ; break;
case 0x3: sprintf(temp1, "(R%d)+N%d", n1, n1);
sprintf(temp2, "(R%d)+N%d", n2, n2); break;
}
ea1 = temp1;
ea2 = temp2;
}
void assemble_ea_from_MM_table(UINT16 MM, int n, std::string& ea)
{
char temp[32];
switch(MM)
{
case 0x0: sprintf(temp, "(R%d)", n) ; break;
case 0x1: sprintf(temp, "(R%d)+", n) ; break;
case 0x2: sprintf(temp, "(R%d)-", n) ; break;
case 0x3: sprintf(temp, "(R%d)+N%d", n, n); break;
}
ea = temp;
}
void assemble_ea_from_q_table(UINT16 q, int n, std::string& ea)
{
char temp[32];
switch(q)
{
case 0x0: sprintf(temp, "(R%d+N%d)", n, n); break;
case 0x1: sprintf(temp, "-(R%d)", n) ; break;
}
ea = temp;
}
void assemble_ea_from_t_table(UINT16 t, UINT16 val, std::string& ea)
{
char temp[32];
switch(t)
{
case 0x0: sprintf(temp, "X:>$%x", val); break;
case 0x1: sprintf(temp, "#>$%x", val); break;
// NEW // case 0x0: sprintf(ea, "X:$%04x", val); break;
// NEW // case 0x1: sprintf(ea, "#$%04x", val); break;
}
ea = temp;
}
void assemble_ea_from_z_table(UINT16 z, int n, std::string& ea)
{
char temp[32];
switch(z)
{
case 0x0: sprintf(temp, "(R%d)-", n) ; break;
case 0x1: sprintf(temp, "(R%d)+N%d", n, n); break;
}
ea = temp;
}
void assemble_D_from_P_table(UINT16 P, UINT16 ppppp, std::string& D)
{
char temp[32];
std::string fullAddy; /* Convert Short Absolute Address to full 16-bit */
switch(P)
{
case 0x0:
sprintf(temp, "X:<$%x", ppppp);
// NEW // sprintf(temp, "X:$%02x", ppppp);
break;
case 0x1:
assemble_address_from_IO_short_address(ppppp, fullAddy);
sprintf(temp, "X:<<$%s", fullAddy.c_str());
// NEW // sprintf(temp, "X:$%s", fullAddy.c_str());
break;
}
D = temp;
}
void assemble_arguments_from_W_table(UINT16 W, char ma, const std::string& SD, const std::string& ea,
std::string& source, std::string& destination)
{
char temp[32];
sprintf(temp, "%c:%s", ma, ea.c_str());
switch(W)
{
case 0x0: source = SD; destination = temp; break;
case 0x1: source = temp; destination = SD; break;
}
}
void assemble_reg_from_W_table(UINT16 W, char ma, const std::string& SD, const INT8 xx, std::string& S, std::string& D)
{
UINT8 abs_xx;
char temp[32];
char operation[32];
if(xx < 0)
sprintf(operation,"-");
else
sprintf(operation,"+");
abs_xx = abs(xx);
sprintf(temp, "%c:(R2%s$%x)", ma, operation, abs_xx);
// NEW // sprintf(temp, "%c:(R2%s$%02x)", ma, operation, abs_xx);
switch(W)
{
case 0x0: S = SD; D = temp; break;
case 0x1: S = temp; D = SD; break;
}
}
void assemble_address_from_IO_short_address(UINT16 pp, std::string& ea)
{
char temp[32];
UINT16 fullAddy = 0xffe0;
fullAddy |= pp;
sprintf(temp, "%.04x", fullAddy);
ea = temp;
}
INT8 get_6_bit_signed_value(UINT16 bits)
{
UINT16 fullAddy = bits;
if (fullAddy & 0x0020)
fullAddy |= 0xffc0;
return (INT8)fullAddy;
}
/*******************/
/* HELPER FUNCTION */
/*******************/
UINT16 dsp56k_op_maskn(UINT16 cur, UINT16 mask)
{
int i;
UINT16 retVal = (cur & mask);
UINT16 temp = 0x0000;
int offsetCount = 0;
/* Shift everything right, eliminating 'whitespace'... */
for (i = 0; i < 16; i++)
{
if (mask & (0x1<<i)) /* If mask bit is non-zero */
{
temp |= (((retVal >> i) & 0x1) << offsetCount);
offsetCount++;
}
}
return temp;
}
bool registerOverlap(const std::string& r0, const size_t bmd, const std::string& r1)
{
if (bmd == BM_NONE)
return false;
if (r0 == r1)
return true;
if (r0 == "A" && (bmd & BM_LOW) && r1 == "A0") return true;
if (r0 == "A" && (bmd & BM_MIDDLE) && r1 == "A1") return true;
if (r0 == "A" && (bmd & BM_HIGH) && r1 == "A2") return true;
if (r0 == "B" && (bmd & BM_LOW) && r1 == "B0") return true;
if (r0 == "B" && (bmd & BM_MIDDLE) && r1 == "B1") return true;
if (r0 == "B" && (bmd & BM_HIGH) && r1 == "B2") return true;
return false;
}
}

View File

@ -0,0 +1,68 @@
#ifndef __DSP56K_OPS_H__
#define __DSP56K_OPS_H__
#include <string>
#include <cstdio>
#include <cstdlib>
#include "emu.h"
namespace DSP56K
{
#define BITSn(CUR,MASK) (dsp56k_op_maskn(CUR,MASK))
enum bbbType {BBB_UPPER, BBB_MIDDLE, BBB_LOWER, BBB_INVALID};
enum bitsModified {BM_NONE = 0x0,
BM_LOW = 0x1,
BM_MIDDLE = 0x2,
BM_HIGH = 0x4};
int decode_BBB_table(UINT16 BBB);
void decode_cccc_table(const UINT16 cccc, std::string& mnemonic);
void decode_DDDDD_table(const UINT16 DDDDD, std::string& SD);
void decode_DD_table(const UINT16 DD, std::string& SD);
void decode_DDF_table(const UINT16 DD, const UINT16 F, std::string& S, std::string& D);
void decode_EE_table(const UINT16 EE, std::string& D);
void decode_F_table(const UINT16 F, std::string& SD);
void decode_h0hF_table(const UINT16 h0h, UINT16 F, std::string& S, std::string& D);
void decode_HH_table(const UINT16 HH, std::string& SD);
void decode_HHH_table(const UINT16 HHH, std::string& SD);
void decode_IIIIx_table(const UINT16 IIII, const UINT16 x, std::string& S, std::string& D);
void decode_JJJF_table(const UINT16 JJJ, const UINT16 F, std::string& S, std::string& D);
void decode_JJF_table(const UINT16 JJ, const UINT16 F, std::string& S, std::string& D);
void decode_JF_table(const UINT16 J, const UINT16 F, std::string& S, std::string& D);
void decode_kSign_table(const UINT16 k, std::string& plusMinus);
void decode_KKK_table(const UINT16 KKK, std::string& D1, std::string& D2);
void decode_NN_table(UINT16 NN, INT8& ret);
void decode_TT_table(UINT16 TT, INT8& ret);
void decode_QQF_table(const UINT16 QQ, const UINT16 F, std::string& S1, std::string& S2, std::string& D);
void decode_QQF_special_table(const UINT16 QQ, const UINT16 F, std::string& S1, std::string& S2, std::string& D);
void decode_QQQF_table(const UINT16 QQQ, const UINT16 F, std::string& S1, std::string& S2, std::string& D);
void decode_RR_table(UINT16 RR, INT8& ret);
void decode_rr_table(UINT16 rr, INT8& ret);
void decode_s_table(const UINT16 s, std::string& arithmetic);
void decode_ss_table(const UINT16 ss, std::string& arithmetic);
void decode_uuuuF_table(const UINT16 uuuu, const UINT16 F, std::string& arg, std::string& S, std::string& D);
void decode_Z_table(const UINT16 Z, std::string& ea);
void assemble_ea_from_m_table(const UINT16 m, const int n, std::string& ea);
void assemble_eas_from_mm_table(UINT16 mm, int n1, int n2, std::string& ea1, std::string& ea2);
void assemble_ea_from_MM_table(UINT16 MM, int n, std::string& ea);
void assemble_ea_from_q_table(UINT16 q, int n, std::string& ea);
void assemble_ea_from_t_table(UINT16 t, UINT16 val, std::string& ea);
void assemble_ea_from_z_table(UINT16 z, int n, std::string& ea);
void assemble_D_from_P_table(UINT16 P, UINT16 ppppp, std::string& D);
void assemble_arguments_from_W_table(UINT16 W, char ma, const std::string& SD, const std::string& ea, std::string& S, std::string& D);
void assemble_reg_from_W_table(UINT16 W, char ma, const std::string& SD, const INT8 xx, std::string& S, std::string& D);
void assemble_address_from_IO_short_address(UINT16 pp, std::string& ea);
INT8 get_6_bit_signed_value(UINT16 bits);
// Helpers
UINT16 dsp56k_op_maskn(UINT16 cur, UINT16 mask);
bool registerOverlap(const std::string& r0, const size_t bmd, const std::string& r1);
}
#endif

View File

@ -111,7 +111,7 @@ jedutil$(EXE): $(JEDUTILOBJS) $(LIBUTIL) $(LIBOCORE) $(ZLIB) $(EXPAT)
UNIDASMOBJS = \ UNIDASMOBJS = \
$(TOOLSOBJ)/unidasm.o \ $(TOOLSOBJ)/unidasm.o \
unidasm$(EXE): $(UNIDASMOBJS) $(LIBDASM) $(LIBUTIL) $(LIBOCORE) $(ZLIB) $(EXPAT) unidasm$(EXE): $(UNIDASMOBJS) $(LIBDASM) $(LIBEMU) $(LIBUTIL) $(LIBOCORE) $(ZLIB) $(EXPAT)
@echo Linking $@... @echo Linking $@...
$(LD) $(LDFLAGS) $^ $(LIBS) -o $@ $(LD) $(LDFLAGS) $^ $(LIBS) -o $@

View File

@ -333,18 +333,6 @@ static const dasm_table_entry dasm_table[] =
{ "z8", _8bit, 0, CPU_DISASSEMBLE_NAME(z8) }, { "z8", _8bit, 0, CPU_DISASSEMBLE_NAME(z8) },
}; };
void *malloc_file_line(size_t size, const char *file, int line)
{
void *result = malloc(size);
return result;
}
void free_file_line(void *memory, const char *file, int line)
{
free(memory);
}
void CLIB_DECL logerror(const char *format, ...) void CLIB_DECL logerror(const char *format, ...)
{ {
/* silent logerrors are allowed in disassemblers */ /* silent logerrors are allowed in disassemblers */