1 // license:BSD-3-Clause
2 // copyright-holders:Curt Coder
3 /***************************************************************************
4 
5     cop424ds.c
6 
7     National Semiconductor COP424C/COP444C Emulator.
8 
9 ***************************************************************************/
10 
11 #include "emu.h"
12 #include "cop424ds.h"
13 
opcode_alignment() const14 u32 cop424_disassembler::opcode_alignment() const
15 {
16 	return 1;
17 }
18 
disassemble(std::ostream & stream,offs_t pc,const data_buffer & opcodes,const data_buffer & params)19 offs_t cop424_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer &params)
20 {
21 	uint8_t opcode = opcodes.r8(pc);
22 	uint8_t next_opcode = opcodes.r8(pc+1);
23 	uint16_t address;
24 	uint32_t flags = 0;
25 	int bytes = 1;
26 
27 	if ((opcode >= 0x80 && opcode <= 0xBE) || (opcode >= 0xC0 && opcode <= 0xFE))
28 	{
29 		int page = pc >> 6;
30 
31 		if (page == 2 || page == 3) //JP pages 2,3
32 		{
33 			address = (uint16_t)((pc & 0x780) | (opcode & 0x7F));
34 			util::stream_format(stream, "JP %03X", address);
35 		}
36 		else
37 		{
38 			if ((opcode & 0xC0) == 0xC0) //JP other pages
39 			{
40 				address = (uint16_t)((pc & 0x7C0) | (opcode & 0x3F));
41 				util::stream_format(stream, "JP %03X", address);
42 			}
43 			else                    //JSRP
44 			{
45 				address = (uint16_t)(0x80 | (opcode & 0x3F));
46 				util::stream_format(stream, "JSRP %03X", address);
47 				flags = STEP_OVER;
48 			}
49 		}
50 	}
51 	else if (opcode >= 0x08 && opcode <= 0x0F)
52 	{
53 		util::stream_format(stream, "LBI 0,%u", ((opcode & 0xF) + 1) & 0xF);
54 	}
55 	else if (opcode >= 0x18 && opcode <= 0x1F)
56 	{
57 		util::stream_format(stream, "LBI 1,%u", ((opcode & 0xF) + 1) & 0xF);
58 	}
59 	else if (opcode >= 0x28 && opcode <= 0x2F)
60 	{
61 		util::stream_format(stream, "LBI 2,%u", ((opcode & 0xF) + 1) & 0xF);
62 	}
63 	else if (opcode >= 0x38 && opcode <= 0x3F)
64 	{
65 		util::stream_format(stream, "LBI 3,%u", ((opcode & 0xF) + 1) & 0xF);
66 	}
67 	else if (opcode >= 0x51 && opcode <= 0x5F)
68 	{
69 		util::stream_format(stream, "AISC %u", opcode & 0xF);
70 	}
71 	else if (opcode >= 0x60 && opcode <= 0x67)
72 	{
73 		address = ((opcode & 0x07) << 8) | next_opcode;
74 		util::stream_format(stream, "JMP %03X", address);
75 		bytes = 2;
76 	}
77 	else if (opcode >= 0x68 && opcode <= 0x6f)
78 	{
79 		address = ((opcode & 0x07) << 8) | next_opcode;
80 		util::stream_format(stream, "JSR %03X", address);
81 		flags = STEP_OVER;
82 		bytes = 2;
83 	}
84 	else if (opcode >= 0x70 && opcode <= 0x7F)
85 	{
86 		util::stream_format(stream, "STII %u", opcode & 0xF);
87 	}
88 	else
89 	{
90 		switch (opcode)
91 		{
92 		case 0:
93 			util::stream_format(stream, "CLRA");
94 			break;
95 
96 		case 1:
97 			util::stream_format(stream, "SKMBZ 0");
98 			break;
99 
100 		case 2:
101 			util::stream_format(stream, "XOR");
102 			break;
103 
104 		case 3:
105 			util::stream_format(stream, "SKMBZ 2");
106 			break;
107 
108 		case 4:
109 			util::stream_format(stream, "XIS 0");
110 			break;
111 
112 		case 5:
113 			util::stream_format(stream, "LD 0");
114 			break;
115 
116 		case 6:
117 			util::stream_format(stream, "X 0");
118 			break;
119 
120 		case 7:
121 			util::stream_format(stream, "XDS 0");
122 			break;
123 
124 		case 0x10:
125 			util::stream_format(stream, "CASC");
126 			break;
127 
128 		case 0x11:
129 			util::stream_format(stream, "SKMBZ 1");
130 			break;
131 
132 		case 0x12:
133 			util::stream_format(stream, "XABR");
134 			break;
135 
136 		case 0x13:
137 			util::stream_format(stream, "SKMBZ 3");
138 			break;
139 
140 		case 0x14:
141 			util::stream_format(stream, "XIS 1");
142 			break;
143 
144 		case 0x15:
145 			util::stream_format(stream, "LD 1");
146 			break;
147 
148 		case 0x16:
149 			util::stream_format(stream, "X 1");
150 			break;
151 
152 		case 0x17:
153 			util::stream_format(stream, "XDS 1");
154 			break;
155 
156 		case 0x20:
157 			util::stream_format(stream, "SKC");
158 			break;
159 
160 		case 0x21:
161 			util::stream_format(stream, "SKE");
162 			break;
163 
164 		case 0x22:
165 			util::stream_format(stream, "SC");
166 			break;
167 
168 		case 0x23:
169 			bytes = 2;
170 
171 			if (next_opcode <= 0x7f)
172 			{
173 				address = (uint16_t)(next_opcode & 0x7F);
174 				util::stream_format(stream, "LDD %u,%u", address >> 4, address & 0x0F);
175 			}
176 			else if (next_opcode >= 0x80)
177 			{
178 				address = (uint16_t)(next_opcode & 0x7f);
179 				util::stream_format(stream, "XAD %u,%u", address >> 4, address & 0x0F);
180 			}
181 			break;
182 
183 		case 0x24:
184 			util::stream_format(stream, "XIS 2");
185 			break;
186 
187 		case 0x25:
188 			util::stream_format(stream, "LD 2");
189 			break;
190 
191 		case 0x26:
192 			util::stream_format(stream, "X 2");
193 			break;
194 
195 		case 0x27:
196 			util::stream_format(stream, "XDS 2");
197 			break;
198 
199 		case 0x30:
200 			util::stream_format(stream, "ASC");
201 			break;
202 
203 		case 0x31:
204 			util::stream_format(stream, "ADD");
205 			break;
206 
207 		case 0x32:
208 			util::stream_format(stream, "RC");
209 			break;
210 
211 		case 0x33:
212 			bytes = 2;
213 
214 			if (next_opcode >= 0x50 && next_opcode <= 0x5F)
215 			{
216 				util::stream_format(stream, "OGI %u", next_opcode & 0xF);
217 			}
218 			else if (next_opcode >= 0x60 && next_opcode <= 0x6F)
219 			{
220 				util::stream_format(stream, "LEI %u", next_opcode & 0xF);
221 			}
222 			else if (next_opcode >= 0x80)
223 			{
224 				util::stream_format(stream, "LBI %u,%u", (next_opcode >> 4) & 0x07, next_opcode & 0xF);
225 			}
226 			else
227 			{
228 				switch (next_opcode)
229 				{
230 				case 0x01:
231 					util::stream_format(stream, "SKGBZ 0");
232 					break;
233 
234 				case 0x03:
235 					util::stream_format(stream, "SKGBZ 2");
236 					break;
237 
238 				case 0x11:
239 					util::stream_format(stream, "SKGBZ 1");
240 					break;
241 
242 				case 0x13:
243 					util::stream_format(stream, "SKGBZ 3");
244 					break;
245 
246 				case 0x21:
247 					util::stream_format(stream, "SKGZ");
248 					break;
249 
250 				case 0x28:
251 					util::stream_format(stream, "ININ");
252 					break;
253 
254 				case 0x29:
255 					util::stream_format(stream, "INIL");
256 					break;
257 
258 				case 0x2A:
259 					util::stream_format(stream, "ING");
260 					break;
261 
262 				case 0x2C:
263 					util::stream_format(stream, "CQMA");
264 					break;
265 
266 				case 0x2E:
267 					util::stream_format(stream, "INL");
268 					break;
269 
270 				case 0x2F:
271 					util::stream_format(stream, "CTMA");
272 					break;
273 
274 				case 0x38:
275 					util::stream_format(stream, "HALT");
276 					break;
277 
278 				case 0x39:
279 					util::stream_format(stream, "IT");
280 					break;
281 
282 				case 0x3A:
283 					util::stream_format(stream, "OMG");
284 					break;
285 
286 				case 0x3C:
287 					util::stream_format(stream, "CAMQ");
288 					break;
289 
290 				case 0x3E:
291 					util::stream_format(stream, "OBD");
292 					break;
293 
294 				case 0x3F:
295 					util::stream_format(stream, "CAMT");
296 					break;
297 
298 
299 				default:
300 					util::stream_format(stream, "Invalid");
301 					break;
302 				}
303 			}
304 			break;
305 
306 		case 0x34:
307 			util::stream_format(stream, "XIS 3");
308 			break;
309 
310 		case 0x35:
311 			util::stream_format(stream, "LD 3");
312 			break;
313 
314 		case 0x36:
315 			util::stream_format(stream, "X 3");
316 			break;
317 
318 		case 0x37:
319 			util::stream_format(stream, "XDS 3");
320 			break;
321 
322 		case 0x40:
323 			util::stream_format(stream, "COMP");
324 			break;
325 
326 		case 0x41:
327 			util::stream_format(stream, "SKT");
328 			break;
329 
330 		case 0x42:
331 			util::stream_format(stream, "RMB 2");
332 			break;
333 
334 		case 0x43:
335 			util::stream_format(stream, "RMB 3");
336 			break;
337 
338 		case 0x44:
339 			util::stream_format(stream, "NOP");
340 			break;
341 
342 		case 0x45:
343 			util::stream_format(stream, "RMB 1");
344 			break;
345 
346 		case 0x46:
347 			util::stream_format(stream, "SMB 2");
348 			break;
349 
350 		case 0x47:
351 			util::stream_format(stream, "SMB 1");
352 			break;
353 
354 		case 0x48:
355 			util::stream_format(stream, "RET");
356 			flags = STEP_OUT;
357 			break;
358 
359 		case 0x49:
360 			util::stream_format(stream, "RETSK");
361 			flags = STEP_OUT;
362 			break;
363 
364 		case 0x4A:
365 			util::stream_format(stream, "ADT");
366 			break;
367 
368 		case 0x4B:
369 			util::stream_format(stream, "SMB 3");
370 			break;
371 
372 		case 0x4C:
373 			util::stream_format(stream, "RMB 0");
374 			break;
375 
376 		case 0x4D:
377 			util::stream_format(stream, "SMB 0");
378 			break;
379 
380 		case 0x4E:
381 			util::stream_format(stream, "CBA");
382 			break;
383 
384 		case 0x4F:
385 			util::stream_format(stream, "XAS");
386 			break;
387 
388 		case 0x50:
389 			util::stream_format(stream, "CAB");
390 			break;
391 
392 		case 0xBF:
393 			util::stream_format(stream, "LQID");
394 			break;
395 
396 		case 0xFF:
397 			util::stream_format(stream, "JID");
398 			break;
399 
400 		default:
401 			util::stream_format(stream, "Invalid");
402 			break;
403 		}
404 	}
405 
406 	return bytes | flags | SUPPORTED;
407 }
408