1 // license:BSD-3-Clause
2 // copyright-holders:R. Belmont,byuu
3 /***************************************************************************
4 
5     dasm7725.c
6     Disassembler for the portable uPD7725 emulator.
7     Written by byuu
8     MAME conversion by R. Belmont
9 
10 ***************************************************************************/
11 
12 #include "emu.h"
13 #include "dasm7725.h"
14 
opcode_alignment() const15 u32 necdsp_disassembler::opcode_alignment() const
16 {
17 	return 1;
18 }
19 
disassemble(std::ostream & stream,offs_t pc,const data_buffer & opcodes,const data_buffer & params)20 offs_t necdsp_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer &params)
21 {
22 	uint32_t opcode = opcodes.r32(pc) >> 8;
23 	uint32_t type = (opcode >> 22);
24 
25 //  printf("dasm: PC %x opcode %08x\n", pc, opcode);
26 
27 	if(type == 0 || type == 1) {  //OP,RT
28 		uint8_t pselect = (opcode >> 20)&0x3;  //P select
29 		uint8_t alu     = (opcode >> 16)&0xf;  //ALU operation mode
30 		uint8_t asl     = (opcode >> 15)&0x1;  //accumulator select
31 		uint8_t dpl     = (opcode >> 13)&0x3;  //DP low modify
32 		uint8_t dphm    = (opcode >>  9)&0xf;  //DP high XOR modify
33 		uint8_t rpdcr   = (opcode >>  8)&0x1;  //RP decrement
34 		uint8_t src     = (opcode >>  4)&0xf;  //move source
35 		uint8_t dst     = (opcode >>  0)&0xf;  //move destination
36 
37 	switch(alu) {
38 		case  0: stream << "nop  "; break;
39 		case  1: stream << "or   "; break;
40 		case  2: stream << "and  "; break;
41 		case  3: stream << "xor  "; break;
42 		case  4: stream << "sub  "; break;
43 		case  5: stream << "add  "; break;
44 		case  6: stream << "sbb  "; break;
45 		case  7: stream << "adc  "; break;
46 		case  8: stream << "dec  "; break;
47 		case  9: stream << "inc  "; break;
48 		case 10: stream << "cmp  "; break;
49 		case 11: stream << "shr1 "; break;
50 		case 12: stream << "shl1 "; break;
51 		case 13: stream << "shl2 "; break;
52 		case 14: stream << "shl4 "; break;
53 		case 15: stream << "xchg "; break;
54 	}
55 
56 	if(alu < 8) {
57 		switch(pselect) {
58 		case 0: stream << "ram,"; break;
59 		case 1: stream << "idb,"; break;
60 		case 2: stream << "m,"; break;
61 		case 3: stream << "n,"; break;
62 		}
63 	}
64 
65 	switch(asl) {
66 		case 0: stream << "a"; break;
67 		case 1: stream << "b"; break;
68 	}
69 
70 	if(dst) {
71 		stream << " | mov ";
72 
73 		switch(src) {
74 		case  0: stream << "trb,"; break;
75 		case  1: stream << "a,"; break;
76 		case  2: stream << "b,"; break;
77 		case  3: stream << "tr,"; break;
78 		case  4: stream << "dp,"; break;
79 		case  5: stream << "rp,"; break;
80 		case  6: stream << "ro,"; break;
81 		case  7: stream << "sgn,"; break;
82 		case  8: stream << "dr,"; break;
83 		case  9: stream << "drnf,"; break;
84 		case 10: stream << "sr,"; break;
85 		case 11: stream << "sim,"; break;
86 		case 12: stream << "sil,"; break;
87 		case 13: stream << "k,"; break;
88 		case 14: stream << "l,"; break;
89 		case 15: stream << "mem,"; break;
90 		}
91 
92 		switch(dst) {
93 		case  0: stream << "non"; break;
94 		case  1: stream << "a"; break;
95 		case  2: stream << "b"; break;
96 		case  3: stream << "tr"; break;
97 		case  4: stream << "dp"; break;
98 		case  5: stream << "rp"; break;
99 		case  6: stream << "dr"; break;
100 		case  7: stream << "sr"; break;
101 		case  8: stream << "sol"; break;
102 		case  9: stream << "som"; break;
103 		case 10: stream << "k"; break;
104 		case 11: stream << "klr"; break;
105 		case 12: stream << "klm"; break;
106 		case 13: stream << "l"; break;
107 		case 14: stream << "trb"; break;
108 		case 15: stream << "mem"; break;
109 		}
110 	}
111 
112 	if(dpl) {
113 		switch(dpl) {
114 		case 0: stream << " | dpnop"; break;
115 		case 1: stream << " | dpinc"; break;
116 		case 2: stream << " | dpdec"; break;
117 		case 3: stream << " | dpclr"; break;
118 		}
119 	}
120 
121 	if(dphm) {
122 		switch(dphm) {
123 		case  0: stream << " | m0"; break;
124 		case  1: stream << " | m1"; break;
125 		case  2: stream << " | m2"; break;
126 		case  3: stream << " | m3"; break;
127 		case  4: stream << " | m4"; break;
128 		case  5: stream << " | m5"; break;
129 		case  6: stream << " | m6"; break;
130 		case  7: stream << " | m7"; break;
131 		case  8: stream << " | m8"; break;
132 		case  9: stream << " | m9"; break;
133 		case 10: stream << " | ma"; break;
134 		case 11: stream << " | mb"; break;
135 		case 12: stream << " | mc"; break;
136 		case 13: stream << " | md"; break;
137 		case 14: stream << " | me"; break;
138 		case 15: stream << " | mf"; break;
139 		}
140 	}
141 
142 	if(rpdcr == 1) {
143 		stream << " | rpdec";
144 	}
145 
146 	if(type == 1) {
147 		stream << " | ret";
148 	}
149 	}
150 
151 	if(type == 2) {  //JP
152 		uint16_t brch = (opcode >> 13) & 0x1ff;  //branch
153 		uint16_t na  = (opcode >>  2) & 0x7ff;  //next address
154 
155 	switch(brch) {
156 		case 0x000: stream << "jmpso "; break;
157 		case 0x080: stream << "jnca "; break;
158 		case 0x082: stream << "jca "; break;
159 		case 0x084: stream << "jncb "; break;
160 		case 0x086: stream << "jcb "; break;
161 		case 0x088: stream << "jnza "; break;
162 		case 0x08a: stream << "jza "; break;
163 		case 0x08c: stream << "jnzb "; break;
164 		case 0x08e: stream << "jzb "; break;
165 		case 0x090: stream << "jnova0 "; break;
166 		case 0x092: stream << "jova0 "; break;
167 		case 0x094: stream << "jnovb0 "; break;
168 		case 0x096: stream << "jovb0 "; break;
169 		case 0x098: stream << "jnova1 "; break;
170 		case 0x09a: stream << "jova1 "; break;
171 		case 0x09c: stream << "jnovb1 "; break;
172 		case 0x09e: stream << "jovb1 "; break;
173 		case 0x0a0: stream << "jnsa0 "; break;
174 		case 0x0a2: stream << "jsa0 "; break;
175 		case 0x0a4: stream << "jnsb0 "; break;
176 		case 0x0a6: stream << "jsb0 "; break;
177 		case 0x0a8: stream << "jnsa1 "; break;
178 		case 0x0aa: stream << "jsa1 "; break;
179 		case 0x0ac: stream << "jnsb1 "; break;
180 		case 0x0ae: stream << "jsb1 "; break;
181 		case 0x0b0: stream << "jdpl0 "; break;
182 		case 0x0b1: stream << "jdpln0 "; break;
183 		case 0x0b2: stream << "jdplf "; break;
184 		case 0x0b3: stream << "jdplnf "; break;
185 		case 0x0b4: stream << "jnsiak "; break;
186 		case 0x0b6: stream << "jsiak "; break;
187 		case 0x0b8: stream << "jnsoak "; break;
188 		case 0x0ba: stream << "jsoak "; break;
189 		case 0x0bc: stream << "jnrqm "; break;
190 		case 0x0be: stream << "jrqm "; break;
191 		case 0x100: stream << "ljmp "; break;
192 		case 0x101: stream << "hjmp "; break;
193 		case 0x140: stream << "lcall "; break;
194 		case 0x141: stream << "hcall "; break;
195 		default:    stream << "??????  "; break;
196 	}
197 
198 	util::stream_format(stream, "$%x", na);
199 	}
200 
201 	if(type == 3) {  //LD
202 	stream << "ld ";
203 	uint16_t id = opcode >> 6;
204 	uint8_t dst = (opcode >> 0) & 0xf;  //destination
205 
206 	util::stream_format(stream, "$%x,", id);
207 
208 	switch(dst) {
209 		case  0: stream << "non"; break;
210 		case  1: stream << "a"; break;
211 		case  2: stream << "b"; break;
212 		case  3: stream << "tr"; break;
213 		case  4: stream << "dp"; break;
214 		case  5: stream << "rp"; break;
215 		case  6: stream << "dr"; break;
216 		case  7: stream << "sr"; break;
217 		case  8: stream << "sol"; break;
218 		case  9: stream << "som"; break;
219 		case 10: stream << "k"; break;
220 		case 11: stream << "klr"; break;
221 		case 12: stream << "klm"; break;
222 		case 13: stream << "l"; break;
223 		case 14: stream << "trb"; break;
224 		case 15: stream << "mem"; break;
225 	}
226 	}
227 
228 	return 1 | SUPPORTED;
229 }
230