1 // license:BSD-3-Clause
2 // copyright-holders:David Haywood
3 /*****************************************************************************
4 
5     AXC51-CORE (AppoTech Inc.)
6 
7     used in
8 
9     AX208 SoC
10 
11  *****************************************************************************/
12 
13 #include "emu.h"
14 #include "axc51-core_dasm.h"
15 
16 // SOME of these might be AX208 specific, we do not currently hvae enough information to split it into AXC51 / AX208 however
17 const axc51core_disassembler::mem_info axc51core_disassembler::axc51core_names[] = {
18 
19 	// SFR Registers
20 	{ 0x80, "P0" },
21 	{ 0x81, "SP" }, // Stack Pointer
22 	{ 0x82, "DPL0" },
23 	{ 0x83, "DPH0" },
24 	{ 0x84, "DPL1" },
25 	{ 0x85, "DPH1" },
26 	{ 0x86, "DPCON" }, // Data Pointer Configure Register
27 	{ 0x87, "PCON0" }, // Power Control 0
28 	{ 0x88, "SDCON0" },
29 	{ 0x89, "SDCON1" },
30 	{ 0x8A, "SDCON2" },
31 	{ 0x8B, "JPGCON4" },
32 	{ 0x8C, "JPGCON3" },
33 	{ 0x8D, "JPGCON2" },
34 	{ 0x8E, "JPGCON1" },
35 	{ 0x8F, "TRAP" },
36 	{ 0x90, "P1" },
37 	{ 0x91, "SDBAUD" },
38 	{ 0x92, "SDCPTR" },
39 	{ 0x93, "SDDCNT" },
40 	{ 0x94, "SDDPTR" },
41 	{ 0x95, "IE2" }, // Interrupt Enable 2
42 	{ 0x96, "UARTBAUDH" }, // UART Baud (high)
43 	{ 0x97, "PWKEN" }, // Port Wakeup Enable
44 	{ 0x98, "PWKPND" }, //Port Wakeup Flag
45 	{ 0x99, "PWKEDGE" }, // Port Wakeup Edge
46 	{ 0x9A, "PIE0" }, // Port Digital Input Enable Control 0
47 	{ 0x9B, "DBASE" }, // DRAM Base Address Register
48 	{ 0x9C, "PCON1" }, // Power Control 1
49 	{ 0x9D, "PIE1" }, // Port Digital Input Enable Control 1
50 	{ 0x9E, "IRTDATA" }, // IRTCC Communication Data
51 	{ 0x9F, "IRTCON" }, // IRTCC Control
52 	{ 0xA0, "P2" },
53 	{ 0xA1, "GP0" }, // (General Purpose Register 0)
54 	{ 0xA2, "GP1" }, // (General Purpose Register 1)
55 	{ 0xA3, "GP2" }, // (General Purpose Register 2)
56 	{ 0xA4, "GP3" }, // (General Purpose Register 3)
57 	{ 0xA5, "DACCON" }, // DAC Control Register
58 	{ 0xA6, "DACLCH" }, // DAC Left Channel
59 	{ 0xA7, "DACRCH" }, // DAC Right Channel
60 	{ 0xA8, "IE0" }, // Interrupt Enable 0
61 	{ 0xA9, "IE1" }, // Interrupt Enable 1
62 	{ 0xAA, "KEY0" },
63 	{ 0xAB, "KEY1" },
64 	{ 0xAC, "TMR3CON" }, // Timer3 Control
65 	{ 0xAD, "TMR3CNT" }, // Timer3 Counter
66 	{ 0xAE, "TMR3PR" }, // Timer3 Period
67 	{ 0xAF, "TMR3PSR" }, // Timer3 Pre-scalar
68 	{ 0xB0, "P3" },
69 	{ 0xB1, "GP4" }, // (General Purpose Register 4)
70 	{ 0xB2, "GP5" }, // (General Purpose Register 5)
71 	{ 0xB3, "GP6" }, // (General Purpose Register 6)
72 	{ 0xB4, "P4" },
73 	{ 0xB5, "GP7" }, // (General Purpose Register 7)
74 	{ 0xB6, "LCDCON" }, // LCD Control Register (or C6?)
75 	{ 0xB7, "PLLCON" }, // PLL Configuration
76 	{ 0xB8, "IP0" }, // Interrupt Priority 0
77 	{ 0xB9, "IP1" }, // Interrupt Priority 1
78 	{ 0xBA, "P0DIR" },
79 	{ 0xBB, "P1DIR" },
80 	{ 0xBC, "P2DIR" },
81 	{ 0xBD, "P3DIR" },
82 	{ 0xBE, "P4DIR" },
83 	{ 0xBF, "LVDCON" }, // LVD Control Register
84 	{ 0xC0, "JPGCON0" },
85 	{ 0xC1, "TMR2CON" }, // Timer2 Control
86 	{ 0xC2, "JPGCON9" },
87 	{ 0xC3, "JPGCON5" },
88 	{ 0xC4, "JPGCON6" },
89 	{ 0xC5, "JPGCON7" },
90 	{ 0xC6, "JPGCON8" },
91 	{ 0xC7, "LCDPR" }, // LCD CS Pulse Width Register
92 	{ 0xC8, "LCDTCON" }, // LCD WR Pulse Timing Control Register
93 	{ 0xC9, "USBCON0" },
94 	{ 0xCA, "USBCON1" },
95 	{ 0xCB, "USBCON2" },
96 	{ 0xCC, "USBDATA" },
97 	{ 0xCD, "USBADR" },
98 	{ 0xCE, "illegal" },
99 	{ 0xCF, "MICCON" }, // MIC Control
100 	{ 0xD0, "PSW" }, // Processor Status Word
101 	{ 0xD1, "PGCON" }, // Power Gate Control Register
102 	{ 0xD2, "ADCCON" }, // SARADC Control
103 	{ 0xD3, "PCON2" }, // Power Control 2
104 	{ 0xD4, "ADCDATAL" }, // SARADC Buffer Low Byte Control
105 	{ 0xD5, "ADCDATAH" }, // SARADC Buffer High Byte Control
106 	{ 0xD6, "SPIDMAADDR" }, // SPI DMA Start Address
107 	{ 0xD7, "SPIDMACNT" }, // SPI DMA counter
108 	{ 0xD8, "SPICON" }, // SPI Control
109 	{ 0xD9, "SPIBUF" }, // SPI Data Buffer
110 	{ 0xDA, "SPIBAUD" }, // SPI Baud Rate
111 	{ 0xDB, "CLKCON" }, // Clock Control
112 	{ 0xDC, "CLKCON1" },
113 	{ 0xDD, "USBDPDM" },
114 	{ 0xDE, "LFSRPOLY0" },
115 	{ 0xDF, "LFSRPOLY1" },
116 	{ 0xE0, "ACC" },
117 	{ 0xE1, "TMR1CON" }, // Timer1 Control
118 	{ 0xE2, "UID0" },
119 	{ 0xE3, "UID1" },
120 	{ 0xE4, "UID2" },
121 	{ 0xE5, "UID3" },
122 	{ 0xE6, "ER00" }, // ER00 \- ER0 (16-bit)  Extended Registers (used by 16-bit opcodes)
123 	{ 0xE7, "ER01" }, // ER01 /
124 	{ 0xE8, "ER10" }, // ER10 \- ER1 (16-bit)
125 	{ 0xE9, "ER11" }, // ER11 /
126 	{ 0xEA, "ER20" }, // ER20 \- ER2 (16-bit)
127 	{ 0xEB, "ER21" }, // ER21 /
128 	{ 0xEC, "ER30" }, // ER30 \- ER3 (16-bit)
129 	{ 0xED, "ER31" }, // ER31 /
130 	{ 0xEE, "ER8" }, // ER8
131 	{ 0xEF, "illegal" },
132 	{ 0xF0, "B" },
133 	{ 0xF1, "HUFFBUF" },
134 	{ 0xF2, "HUFFSFT" },
135 	{ 0xF3, "HUFFDCL" },
136 	{ 0xF4, "HUFFDCH" },
137 	{ 0xF5, "CRC" },
138 	{ 0xF6, "LFSRFIFO" },
139 	{ 0xF7, "WDTCON" }, // Watchdog Control
140 	{ 0xF8, "TMR0CON" }, // Timer0 Control
141 	{ 0xF9, "TMR0CNT" }, // Timer0 Counter
142 	{ 0xFA, "TMR0PR" }, // Timer0 Period
143 	{ 0xFB, "TMR0PSR" }, // Timer0 Pre-scalar
144 	{ 0xFC, "UARTSTA" }, // UART Status
145 	{ 0xFD, "UARTCON" }, // UART Control
146 	{ 0xFE, "UARTBAUD" }, // UART Baud (low)
147 	{ 0xFF, "UARTDATA" }, // UART Communication Data
148 
149 	// Upper Registers
150 
151 	{ 0x3010, "PUP0" },
152 	{ 0x3011, "PUP1" },
153 	{ 0x3012, "PUP2" },
154 	{ 0x3013, "PUP3" },
155 	{ 0x3014, "PUP4" },
156 	{ 0x3015, "PDN0" },
157 	{ 0x3016, "PDN1" },
158 	{ 0x3017, "PDN2" },
159 	{ 0x3018, "PDN3" },
160 	{ 0x3019, "PDN4" },
161 
162 	{ 0x3020, "TMR1CNTL" }, // Timer 1 Counter (low)
163 	{ 0x3021, "TMR1CNTH" }, // Timer 1 Counter (high)
164 	{ 0x3022, "TMR1PRL" }, // Timer 1 Period (low)
165 	{ 0x3023, "TMR1PRH" }, // Timer 1 Period (high)
166 	{ 0x3024, "TMR1PWML" }, // Timer 1 Duty (low)
167 	{ 0x3025, "TMR1PWMH" }, // Timer 1 Duty (high)
168 
169 	{ 0x3030, "TMR2CNTL" }, // Timer 2 Counter (low)
170 	{ 0x3031, "TMR2CNTH" }, // Timer 2 Counter (high)
171 	{ 0x3032, "TMR2PRL" }, // Timer 2 Period (low)
172 	{ 0x3033, "TMR2PRH" }, // Timer 2 Period (high)
173 	{ 0x3034, "TMR2PWML" }, // Timer 2 Duty (low)
174 	{ 0x3035, "TMR2PWMH" }, // Timer 2 Duty (high)
175 
176 	{ 0x3040, "ADCBAUD" }, //S ARADC Baud
177 
178 	{ 0x3050, "USBEP0ADL" },
179 	{ 0x3051, "USBEP0ADH" },
180 	{ 0x3052, "USBEP1RXADL" },
181 	{ 0x3053, "USBEP1RXADH" },
182 	{ 0x3054, "USBEP1TXADL" },
183 	{ 0x3055, "USBEP1TXADH" },
184 	{ 0x3056, "USBEP2RXADL" },
185 	{ 0x3057, "USBEP2RXADH" },
186 	{ 0x3058, "USBEP2TXADL" },
187 	{ 0x3059, "USBEP2TXADH" },
188 
189 	{ 0x3060, "SFSCON" },
190 	{ 0x3061, "SFSPID" },
191 	{ 0x3062, "SFSCNTH" },
192 	{ 0x3063, "SFSCNTL" },
193 
194 	{ 0x3070, "DACPTR" }, // DAC DMA Pointer
195 	{ 0x3071, "DACCNT" }, // DAC DMA Counter
196 
197 	{ -1 }
198 };
199 
200 
201 // based on extracted symbol table, note 0x8000 - 0x8ca3 is likely boot code, interrupt code, kernel etc.
202 // this should be the same for all ax208 CPUs as they are thought to all use the same internal ROM
203 const ax208_disassembler::ax208_bios_info ax208_disassembler::bios_call_names[] = {
204 	{ 0x8000, "entry point" },
205 
206 	{ 0x8006, "unknown, used" },
207 	{ 0x8009, "unknown, used" },
208 
209 	{ 0x8ca4, "_STRCHR" },
210 	{ 0x8dd6, "_STRLEN" },
211 	{ 0x8eb7, "_tolower" },
212 	{ 0x8ec8, "_toupper" },
213 	{ 0x900f, "_isalpha" },
214 	{ 0x902a, "_iscntrl" },
215 	{ 0x9038, "_isdigit" },
216 	{ 0x9047, "_isalnum" },
217 	{ 0x906d, "_isgraph" },
218 	{ 0x907c, "_isprint" },
219 	{ 0x908b, "_ispunct" },
220 	{ 0x90bb, "_islower" },
221 	{ 0x90ca, "_isupper" },
222 	{ 0x90d9, "_isspace" },
223 	{ 0x90ec, "_isxdigit" },
224 	{ 0x91e2, "COPY" },
225 	{ 0x9208, "SCDIV" },
226 	{ 0x922a, "CLDPTR" },
227 	{ 0x9243, "CLDIPTR" },
228 	{ 0x9267, "CLDOPTR" },
229 	{ 0x9294, "CLDIOPTR" },
230 	{ 0x92cb, "CILDPTR" },
231 	{ 0x92ed, "CILDOPTR" },
232 	{ 0x9320, "CSTPTR" },
233 	{ 0x9332, "CSTOPTR" },
234 	{ 0x9354, "UIDIV" },
235 	{ 0x93a9, "SIDIV" },
236 	{ 0x93df, "IILDX" },
237 	{ 0x93f5, "ILDIX" },
238 	{ 0x940b, "ILDPTR" },
239 	{ 0x9436, "ILDIPTR" },
240 	{ 0x946b, "ILDOPTR" },
241 	{ 0x94a3, "ILDIOPTR" },
242 	{ 0x94ef, "IILDPTR" },
243 	{ 0x9527, "IILDOPTR" },
244 	{ 0x9574, "ISTPTR" },
245 	{ 0x9593, "ISTOPTR" },
246 	{ 0x95c0, "LADD" },
247 	{ 0x95cd, "LSUB" },
248 	{ 0x95db, "LMUL" },
249 	{ 0x9666, "ULDIV" },
250 	{ 0x96f8, "LAND" },
251 	{ 0x9705, "LOR" },
252 	{ 0x9712, "LXOR" },
253 	{ 0x971f, "LNOT" },
254 	{ 0x972c, "LNEG" },
255 	{ 0x973a, "SLCMP" },
256 	{ 0x9750, "ULCMP" },
257 	{ 0x9761, "ULSHR" },
258 	{ 0x9774, "SLSHR" },
259 	{ 0x9788, "LSHL" },
260 	{ 0x979b, "LLDPTR" },
261 	{ 0x97bb, "LLDOPTR" },
262 	{ 0x97eb, "LSTPTR" },
263 	{ 0x9805, "LSTOPTR" },
264 	{ 0x9829, "LILDPTR" },
265 	{ 0x9849, "LILDOPTR" },
266 	{ 0x9879, "LLDIPTR" },
267 	{ 0x9899, "LLDIOPTR" },
268 	{ 0x98c9, "LLDIDATA" },
269 	{ 0x98d5, "LLDXDATA" },
270 	{ 0x98e1, "LLDPDATA" },
271 	{ 0x98ed, "LLDCODE" },
272 	{ 0x98fd, "LLDIDATA0" },
273 	{ 0x990a, "LLDXDATA0" },
274 	{ 0x9916, "LLDPDATA0" },
275 	{ 0x9923, "LLDCODE0" },
276 	{ 0x9933, "LLDPTR0" },
277 	{ 0x9953, "LLDOPTR0" },
278 	{ 0x9983, "LLDIIDATA1" },
279 	{ 0x9985, "LLDIIDATA8" },
280 	{ 0x998c, "LLDIIDATA" },
281 	{ 0x99a3, "LLDIXDATA1" },
282 	{ 0x99a5, "LLDIXDATA8" },
283 	{ 0x99ac, "LLDIXDATA" },
284 	{ 0x99d8, "LLDIPDATA1" },
285 	{ 0x99da, "LLDIPDATA8" },
286 	{ 0x99e1, "LLDIPDATA" },
287 	{ 0x99f8, "LILDIDATA1" },
288 	{ 0x99fa, "LILDIDATA8" },
289 	{ 0x9a01, "LILDIDATA" },
290 	{ 0x9a18, "LILDXDATA1" },
291 	{ 0x9a1a, "LILDXDATA8" },
292 	{ 0x9a21, "LILDXDATA" },
293 	{ 0x9a4d, "LILDPDATA1" },
294 	{ 0x9a4f, "LILDPDATA8" },
295 	{ 0x9a56, "LILDPDATA" },
296 	{ 0x9a6d, "LSTIDATA" },
297 	{ 0x9a79, "LSTXDATA" },
298 	{ 0x9a85, "LSTPDATA" },
299 	{ 0x9a91, "LSTKIDATA" },
300 	{ 0x9aaa, "LSTKXDATA" },
301 	{ 0x9adb, "LSTKPDATA" },
302 	{ 0x9af4, "LSTKPTR" },
303 	{ 0x9b0e, "LSTKOPTR" },
304 	{ 0x9b32, "BCAST_L" },
305 	{ 0x9b3b, "OFFX256" },
306 	{ 0x9b4c, "OFFXADD" },
307 	{ 0x9b58, "OFFXADD1" },
308 	{ 0x9b61, "PLDIDATA" },
309 	{ 0x9b6a, "PLDIIDATA" },
310 	{ 0x9b7a, "PILDIDATA" },
311 	{ 0x9b8a, "PSTIDATA" },
312 	{ 0x9b93, "PLDXDATA" },
313 	{ 0x9b9c, "PLDIXDATA" },
314 	{ 0x9bb3, "PILDXDATA" },
315 	{ 0x9bca, "PSTXDATA" },
316 	{ 0x9bd3, "PLDPDATA" },
317 	{ 0x9bdc, "PLDIPDATA" },
318 	{ 0x9bec, "PILDPDATA" },
319 	{ 0x9bfc, "PSTPDATA" },
320 	{ 0x9c05, "PLDCODE" },
321 	{ 0x9c11, "PLDPTR" },
322 	{ 0x9c31, "PLDIPTR" },
323 	{ 0x9c53, "PILDPTR" },
324 	{ 0x9c75, "PSTPTR" },
325 	{ 0x9cc4, "PSTPTRR" },
326 	{ 0x9cf4, "PLDOPTR" },
327 	{ 0x9d24, "PLDIOPTR" },
328 	{ 0x9d56, "PILDOPTR" },
329 	{ 0x9d88, "PSTOPTR" },
330 	{ 0x9de1, "CCASE" },
331 	{ 0x9e07, "ICASE" },
332 	{ 0x9e34, "LCASE" },
333 	{ 0x9e6e, "ICALL" },
334 	{ 0x9e72, "ICALL2" },
335 	{ 0x9e74, "MEMSET" },
336 	{ 0x9ea0, "LROL" },
337 	{ 0x9eb4, "LROR" },
338 	{ 0x9ec8, "SLDIV" },
339 	{ 0x9f47, "SPI_ENCRYPT_ON3" },
340 	{ 0x9f5c, "_lshift9" },
341 	{ 0x9fdc, "SPI_ENCRYPT_CLOSE" },
342 	{ -1, "unknown" }
343 };
344 
axc51core_disassembler()345 axc51core_disassembler::axc51core_disassembler() : mcs51_disassembler(axc51core_names)
346 {
347 }
348 /* Extended 16-bit Opcodes
349 
350 Opcode/params        |    Operation                                        | Flags touched
351 ----------------------------------------------------------------------------------------
352 INCDPi               |                                                     |
353                      |    DPTRi = DPTRi + 1                                |
354 ----------------------------------------------------------------------------------------
355 DECDPi               |                                                     |
356                      |    DPTRi = DPTRi - 1                                |
357 ----------------------------------------------------------------------------------------
358 ADDDPi               |                                                     |
359                      |    DPTRi = DPTRi + {R8, B}                          |
360 ----------------------------------------------------------------------------------------
361 SUBDPi               |                                                     |
362                      |    DPTRi = DPTRi - {R8, B}                          |
363 ----------------------------------------------------------------------------------------
364 INC2DPi              |                                                     |
365                      |    DPTRi = DPTRi + 2                                |
366 ----------------------------------------------------------------------------------------
367 DEC2DPi              |                                                     |
368                      |    DPTRi = DPTRi - 2                                |
369 ----------------------------------------------------------------------------------------
370 ROTR8                |                                                     |
371 EACC, ER8            |    Rotate Right ACC by R8 &0x3 bits                 |
372 ----------------------------------------------------------------------------------------
373 ROTL8                |                                                     |
374 EACC, ER8            |    Rotate Left ACC by R8 &0x3 bits                  |
375 ----------------------------------------------------------------------------------------
376 ADD16                |                                                     |
377 ERp, DPTRi, ERn      |    ERp = XRAM + ERn + EC                            |    EZ, EC
378 DPTRi, ERn, ERp      |    XRAM = ERn + ERp + EC                            |
379 ERp, ERn, ERm        |    ERp = ERn + ERm + EC                             |
380 ----------------------------------------------------------------------------------------
381 SUB16                |                                                     |
382 ERp, DPTRi, ERn      |    ERp = XRAM - ERn - EC                            |    EZ, EC
383 DPTRi, ERn, ERp      |    XRAM = ERn - ERp - EC                            |
384 ERp, ERn, ERm        |    ERp = ERn - ERm - EC                             |
385 ----------------------------------------------------------------------------------------
386 NOT16                |                                                     |
387 ERn                  |    ERn = ~ERn                                       |
388 ----------------------------------------------------------------------------------------
389 CLR16                |                                                     |
390 ERn                  |    ERn = 0                                          |
391 ----------------------------------------------------------------------------------------
392 INC16                |                                                     |
393 ERn                  |    ERn = ERn + 1                                    |    EZ
394 ----------------------------------------------------------------------------------------
395 DEC16                |                                                     |
396 ERn                  |    ERn = ERn - 1                                    |    EZ
397 ----------------------------------------------------------------------------------------
398 ANL16                |                                                     |
399 ERn, DPTRi           |    ERn = XRAM & ERn                                 |    EZ
400 DPTRi, ERn           |    XRAM = XRAM & ERn                                |
401 ERn, ERm             |    ERn = ERn & ERm                                  |
402 ----------------------------------------------------------------------------------------
403 ORL16                |                                                     |
404 ERn, DPTRi           |    ERn = XRAM | ERn                                 |    EZ
405 DPTRi, ERn           |    XRAM = XRAM | ERn                                |
406 ERn, ERm             |    ERn = ERn | ERm                                  |
407 ----------------------------------------------------------------------------------------
408 XRL16                |                                                     |
409 ERn, DPTRi           |    ERn = XRAM ^ ERn                                 |    EZ
410 DPTRi, ERn           |    XRAM = XRAM ^ ERn                                |
411 ERn, ERm             |    ERn = ERn ^ ERm                                  |
412 ----------------------------------------------------------------------------------------
413 MOV16                |                                                     |
414 ERn, DPTRi           |    ERn = XRAM                                       |    EZ
415 DPTRi, ERn           |    XRAM = ERn                                       |
416 ERn, ERm             |    ERn = ERm                                        |
417 ----------------------------------------------------------------------------------------
418 MUL16 (signed)       |                                                     |
419 ERn, ERm             |    {ERn, ERm} = ERn * ERm                           |
420 ----------------------------------------------------------------------------------------
421 MULS16 (sign, satur) |                                                     |
422 ERn, ERm             |    {ERn, ERm} = ERn * ERm                           |
423 ----------------------------------------------------------------------------------------
424 ROTR16               |                                                     |
425 ERn, ER8             |    Rotate Right ERn by ER8 & 0xf bits               |
426 ----------------------------------------------------------------------------------------
427 ROTL16               |                                                     |
428 ERn, ER8             |    Rotate Left ERn by ER8 & 0xf bits                |
429 ----------------------------------------------------------------------------------------
430 SHIFTL   (lsl)       |                                                     |
431 ERn, ER8             |    ERn = ERn >> (ER8 & 0xf)                         |
432 ----------------------------------------------------------------------------------------
433 SHIFTR   (asr)       |                                                     |
434 ERn, ER8             |    ERn = ERn >> (ER8 & 0xf)                         |
435 ----------------------------------------------------------------------------------------
436 ADD16 (saturate)     |                                                     |
437 ERp, DPTRi, ERn      |    ERp = XRAM + ERn + EC                            |    EZ, EC
438 DPTRi, ERn, ERp      |    XRAM = ERn + ERp + EC                            |
439 ERp, ERn, ERm        |    ERp = ERn + ERm + EC                             |
440 ----------------------------------------------------------------------------------------
441 SUB16 (saturate)     |                                                     |
442 ERp, DPTRi, ERn      |    ERp = XRAM - ERn - EC                            |    EZ, EC
443 DPTRi, ERn, ERp      |    XRAM = ERn - ERp - EC                            |
444 ERp, ERn, ERm        |    ERp = ERn - ERm - EC                             |
445 ----------------------------------------------------------------------------------------
446 SWAP16               |                                                     |
447 ERn                  |    Swap upper and lower 8-bits of ERn               |
448 ----------------------------------------------------------------------------------------
449 
450 access to 16-bit registers is mapped in SFR space, from 0xE6 (note, changing SFR bank does NOT update the actual registers)
451 
452 ERn - 16-bit register ER0-ER3 (as data?)
453 ERm - 16-bit register ER0-ER3 (as data?)
454 ERp - 16-bit register ER0-ER3 (as pointer?)
455 EACC = 8-bit accumulator (same as regular opcodes?)
456 EZ = Zero flag (same as regular opcodes?)
457 EC = Carry flag  (same as regular opcodes?)
458 
459 */
460 
disassemble_extended_a5_0e(std::ostream & stream,unsigned PC,offs_t pc,const data_buffer & opcodes,const data_buffer & params)461 offs_t axc51core_disassembler::disassemble_extended_a5_0e(std::ostream& stream, unsigned PC, offs_t pc, const data_buffer& opcodes, const data_buffer& params)
462 {
463 	uint32_t flags = 0;
464 	uint8_t prm2 = params.r8(PC++);
465 
466 	switch (prm2)
467 	{
468 
469 	case 0x00: case 0x01: case 0x04: case 0x05: case 0x08: case 0x09: case 0x0c: case 0x0d:
470 	case 0x10: case 0x11: case 0x14: case 0x15: case 0x18: case 0x19: case 0x1c: case 0x1d:
471 	case 0x20: case 0x21: case 0x24: case 0x25: case 0x28: case 0x29: case 0x2c: case 0x2d:
472 	case 0x30: case 0x31: case 0x34: case 0x35: case 0x38: case 0x39: case 0x3c: case 0x3d:
473 	{
474 		uint8_t p = (prm2 & 0x30) >> 4;
475 		uint8_t n = (prm2 & 0x0c) >> 2;
476 		uint8_t i = (prm2 & 0x01) >> 0;
477 
478 		util::stream_format(stream, "ADD16 ER%01x, EDP%01x, ER%01x", p, i, n);
479 		break;
480 	}
481 
482 	case 0x02: case 0x03: case 0x06: case 0x07: case 0x0a: case 0x0b: case 0x0e: case 0x0f:
483 	case 0x12: case 0x13: case 0x16: case 0x17: case 0x1a: case 0x1b: case 0x1e: case 0x1f:
484 	case 0x22: case 0x23: case 0x26: case 0x27: case 0x2a: case 0x2b: case 0x2e: case 0x2f:
485 	case 0x32: case 0x33: case 0x36: case 0x37: case 0x3a: case 0x3b: case 0x3e: case 0x3f:
486 	{
487 		uint8_t p = (prm2 & 0x30) >> 4;
488 		uint8_t n = (prm2 & 0x0c) >> 2;
489 		uint8_t i = (prm2 & 0x01) >> 0;
490 
491 		util::stream_format(stream, "ADD16 EDP%01x, ER%01x, ER%01x", i, n, p);
492 		break;
493 	}
494 
495 	case 0x40: case 0x41: case 0x42: case 0x43: case 0x44: case 0x45: case 0x46: case 0x47: case 0x48: case 0x49: case 0x4a: case 0x4b: case 0x4c: case 0x4d: case 0x4e: case 0x4f:
496 	case 0x50: case 0x51: case 0x52: case 0x53: case 0x54: case 0x55: case 0x56: case 0x57: case 0x58: case 0x59: case 0x5a: case 0x5b: case 0x5c: case 0x5d: case 0x5e: case 0x5f:
497 	case 0x60: case 0x61: case 0x62: case 0x63: case 0x64: case 0x65: case 0x66: case 0x67: case 0x68: case 0x69: case 0x6a: case 0x6b: case 0x6c: case 0x6d: case 0x6e: case 0x6f:
498 	case 0x70: case 0x71: case 0x72: case 0x73: case 0x74: case 0x75: case 0x76: case 0x77: case 0x78: case 0x79: case 0x7a: case 0x7b: case 0x7c: case 0x7d: case 0x7e: case 0x7f:
499 	{
500 		uint8_t p = (prm2 & 0x30) >> 4;
501 		uint8_t n = (prm2 & 0x0c) >> 2;
502 		uint8_t m = (prm2 & 0x03) >> 0;
503 		util::stream_format(stream, "ADD16 ER%01x, ER%01x, ER%01x", p, n, m);
504 		break;
505 	}
506 
507 	default:
508 		util::stream_format(stream, "illegal ax208 a5 0e $%02X", prm2);
509 		break;
510 	}
511 
512 	return (PC - pc) | flags | SUPPORTED;
513 }
514 
disassemble_extended_a5_0f(std::ostream & stream,unsigned PC,offs_t pc,const data_buffer & opcodes,const data_buffer & params)515 offs_t axc51core_disassembler::disassemble_extended_a5_0f(std::ostream& stream, unsigned PC, offs_t pc, const data_buffer& opcodes, const data_buffer& params)
516 {
517 	uint32_t flags = 0;
518 	uint8_t prm2 = params.r8(PC++);
519 
520 	switch (prm2)
521 	{
522 
523 	case 0x00: case 0x01: case 0x04: case 0x05: case 0x08: case 0x09: case 0x0c: case 0x0d:
524 	case 0x10: case 0x11: case 0x14: case 0x15: case 0x18: case 0x19: case 0x1c: case 0x1d:
525 	case 0x20: case 0x21: case 0x24: case 0x25: case 0x28: case 0x29: case 0x2c: case 0x2d:
526 	case 0x30: case 0x31: case 0x34: case 0x35: case 0x38: case 0x39: case 0x3c: case 0x3d:
527 	{
528 		uint8_t p = (prm2 & 0x30) >> 4;
529 		uint8_t n = (prm2 & 0x0c) >> 2;
530 		uint8_t i = (prm2 & 0x01) >> 0;
531 
532 		util::stream_format(stream, "SUB16 ER%01x, EDP%01x, ER%01x", p, i, n);
533 		break;
534 	}
535 
536 	case 0x02: case 0x03: case 0x06: case 0x07: case 0x0a: case 0x0b: case 0x0e: case 0x0f:
537 	case 0x12: case 0x13: case 0x16: case 0x17: case 0x1a: case 0x1b: case 0x1e: case 0x1f:
538 	case 0x22: case 0x23: case 0x26: case 0x27: case 0x2a: case 0x2b: case 0x2e: case 0x2f:
539 	case 0x32: case 0x33: case 0x36: case 0x37: case 0x3a: case 0x3b: case 0x3e: case 0x3f:
540 	{
541 		uint8_t p = (prm2 & 0x30) >> 4;
542 		uint8_t n = (prm2 & 0x0c) >> 2;
543 		uint8_t i = (prm2 & 0x01) >> 0;
544 
545 		util::stream_format(stream, "SUB16 EDP%01x, ER%01x, ER%01x", i, n, p);
546 		break;
547 	}
548 
549 	case 0x40: case 0x41: case 0x42: case 0x43: case 0x44: case 0x45: case 0x46: case 0x47: case 0x48: case 0x49: case 0x4a: case 0x4b: case 0x4c: case 0x4d: case 0x4e: case 0x4f:
550 	case 0x50: case 0x51: case 0x52: case 0x53: case 0x54: case 0x55: case 0x56: case 0x57: case 0x58: case 0x59: case 0x5a: case 0x5b: case 0x5c: case 0x5d: case 0x5e: case 0x5f:
551 	case 0x60: case 0x61: case 0x62: case 0x63: case 0x64: case 0x65: case 0x66: case 0x67: case 0x68: case 0x69: case 0x6a: case 0x6b: case 0x6c: case 0x6d: case 0x6e: case 0x6f:
552 	case 0x70: case 0x71: case 0x72: case 0x73: case 0x74: case 0x75: case 0x76: case 0x77: case 0x78: case 0x79: case 0x7a: case 0x7b: case 0x7c: case 0x7d: case 0x7e: case 0x7f:
553 	{
554 		uint8_t p = (prm2 & 0x30) >> 4;
555 		uint8_t n = (prm2 & 0x0c) >> 2;
556 		uint8_t m = (prm2 & 0x03) >> 0;
557 		util::stream_format(stream, "SUB16 ER%01x, ER%01x, ER%01x", p, n, m);
558 		break;
559 	}
560 
561 
562 	default:
563 		util::stream_format(stream, "illegal ax208 a5 0f $%02X", prm2);
564 		break;
565 	}
566 
567 	return (PC - pc) | flags | SUPPORTED;
568 }
569 
disassemble_extended_a5_d0(std::ostream & stream,unsigned PC,offs_t pc,const data_buffer & opcodes,const data_buffer & params)570 offs_t axc51core_disassembler::disassemble_extended_a5_d0(std::ostream& stream, unsigned PC, offs_t pc, const data_buffer& opcodes, const data_buffer& params)
571 {
572 	uint32_t flags = 0;
573 	uint8_t prm2 = params.r8(PC++);
574 
575 	switch (prm2)
576 	{
577 
578 	case 0x00: case 0x01: case 0x04: case 0x05: case 0x08: case 0x09: case 0x0c: case 0x0d:
579 	case 0x10: case 0x11: case 0x14: case 0x15: case 0x18: case 0x19: case 0x1c: case 0x1d:
580 	case 0x20: case 0x21: case 0x24: case 0x25: case 0x28: case 0x29: case 0x2c: case 0x2d:
581 	case 0x30: case 0x31: case 0x34: case 0x35: case 0x38: case 0x39: case 0x3c: case 0x3d:
582 	{
583 		uint8_t p = (prm2 & 0x30) >> 4;
584 		uint8_t n = (prm2 & 0x0c) >> 2;
585 		uint8_t i = (prm2 & 0x01) >> 0;
586 
587 		util::stream_format(stream, "ADDS16 ER%01x, EDP%01x, ER%01x", p, i, n);
588 		break;
589 	}
590 
591 	case 0x02: case 0x03: case 0x06: case 0x07: case 0x0a: case 0x0b: case 0x0e: case 0x0f:
592 	case 0x12: case 0x13: case 0x16: case 0x17: case 0x1a: case 0x1b: case 0x1e: case 0x1f:
593 	case 0x22: case 0x23: case 0x26: case 0x27: case 0x2a: case 0x2b: case 0x2e: case 0x2f:
594 	case 0x32: case 0x33: case 0x36: case 0x37: case 0x3a: case 0x3b: case 0x3e: case 0x3f:
595 	{
596 		uint8_t p = (prm2 & 0x30) >> 4;
597 		uint8_t n = (prm2 & 0x0c) >> 2;
598 		uint8_t i = (prm2 & 0x01) >> 0;
599 
600 		util::stream_format(stream, "ADDS16 EDP%01x, ER%01x, ER%01x", i, n, p);
601 		break;
602 	}
603 
604 	case 0x40: case 0x41: case 0x42: case 0x43: case 0x44: case 0x45: case 0x46: case 0x47: case 0x48: case 0x49: case 0x4a: case 0x4b: case 0x4c: case 0x4d: case 0x4e: case 0x4f:
605 	case 0x50: case 0x51: case 0x52: case 0x53: case 0x54: case 0x55: case 0x56: case 0x57: case 0x58: case 0x59: case 0x5a: case 0x5b: case 0x5c: case 0x5d: case 0x5e: case 0x5f:
606 	case 0x60: case 0x61: case 0x62: case 0x63: case 0x64: case 0x65: case 0x66: case 0x67: case 0x68: case 0x69: case 0x6a: case 0x6b: case 0x6c: case 0x6d: case 0x6e: case 0x6f:
607 	case 0x70: case 0x71: case 0x72: case 0x73: case 0x74: case 0x75: case 0x76: case 0x77: case 0x78: case 0x79: case 0x7a: case 0x7b: case 0x7c: case 0x7d: case 0x7e: case 0x7f:
608 	{
609 		uint8_t p = (prm2 & 0x30) >> 4;
610 		uint8_t n = (prm2 & 0x0c) >> 2;
611 		uint8_t m = (prm2 & 0x03) >> 0;
612 		util::stream_format(stream, "ADDS16 ER%01x, ER%01x, ER%01x", p, n, m);
613 		break;
614 	}
615 
616 	default:
617 		util::stream_format(stream, "illegal ax208 a5 d0 $%02X", prm2);
618 		break;
619 	}
620 
621 	return (PC - pc) | flags | SUPPORTED;
622 }
623 
disassemble_extended_a5_d1(std::ostream & stream,unsigned PC,offs_t pc,const data_buffer & opcodes,const data_buffer & params)624 offs_t axc51core_disassembler::disassemble_extended_a5_d1(std::ostream& stream, unsigned PC, offs_t pc, const data_buffer& opcodes, const data_buffer& params)
625 {
626 	uint32_t flags = 0;
627 	uint8_t prm2 = params.r8(PC++);
628 
629 	switch (prm2)
630 	{
631 
632 	case 0x00: case 0x01: case 0x04: case 0x05: case 0x08: case 0x09: case 0x0c: case 0x0d:
633 	case 0x10: case 0x11: case 0x14: case 0x15: case 0x18: case 0x19: case 0x1c: case 0x1d:
634 	case 0x20: case 0x21: case 0x24: case 0x25: case 0x28: case 0x29: case 0x2c: case 0x2d:
635 	case 0x30: case 0x31: case 0x34: case 0x35: case 0x38: case 0x39: case 0x3c: case 0x3d:
636 	{
637 		uint8_t p = (prm2 & 0x30) >> 4;
638 		uint8_t n = (prm2 & 0x0c) >> 2;
639 		uint8_t i = (prm2 & 0x01) >> 0;
640 
641 		util::stream_format(stream, "SUBS16 ER%01x, EDP%01x, ER%01x", p, i, n);
642 		break;
643 	}
644 
645 	case 0x02: case 0x03: case 0x06: case 0x07: case 0x0a: case 0x0b: case 0x0e: case 0x0f:
646 	case 0x12: case 0x13: case 0x16: case 0x17: case 0x1a: case 0x1b: case 0x1e: case 0x1f:
647 	case 0x22: case 0x23: case 0x26: case 0x27: case 0x2a: case 0x2b: case 0x2e: case 0x2f:
648 	case 0x32: case 0x33: case 0x36: case 0x37: case 0x3a: case 0x3b: case 0x3e: case 0x3f:
649 	{
650 		uint8_t p = (prm2 & 0x30) >> 4;
651 		uint8_t n = (prm2 & 0x0c) >> 2;
652 		uint8_t i = (prm2 & 0x01) >> 0;
653 
654 		util::stream_format(stream, "SUBS16 EDP%01x, ER%01x, ER%01x", i, n, p);
655 		break;
656 	}
657 
658 	case 0x40: case 0x41: case 0x42: case 0x43: case 0x44: case 0x45: case 0x46: case 0x47: case 0x48: case 0x49: case 0x4a: case 0x4b: case 0x4c: case 0x4d: case 0x4e: case 0x4f:
659 	case 0x50: case 0x51: case 0x52: case 0x53: case 0x54: case 0x55: case 0x56: case 0x57: case 0x58: case 0x59: case 0x5a: case 0x5b: case 0x5c: case 0x5d: case 0x5e: case 0x5f:
660 	case 0x60: case 0x61: case 0x62: case 0x63: case 0x64: case 0x65: case 0x66: case 0x67: case 0x68: case 0x69: case 0x6a: case 0x6b: case 0x6c: case 0x6d: case 0x6e: case 0x6f:
661 	case 0x70: case 0x71: case 0x72: case 0x73: case 0x74: case 0x75: case 0x76: case 0x77: case 0x78: case 0x79: case 0x7a: case 0x7b: case 0x7c: case 0x7d: case 0x7e: case 0x7f:
662 	{
663 		uint8_t p = (prm2 & 0x30) >> 4;
664 		uint8_t n = (prm2 & 0x0c) >> 2;
665 		uint8_t m = (prm2 & 0x03) >> 0;
666 		util::stream_format(stream, "SUBS16 ER%01x, ER%01x, ER%01x", p, n, m);
667 		break;
668 	}
669 
670 	default:
671 		util::stream_format(stream, "illegal ax208 a5 d1 $%02X", prm2);
672 		break;
673 	}
674 
675 	return (PC - pc) | flags | SUPPORTED;
676 }
677 
678 
disassemble_extended_a5(std::ostream & stream,unsigned PC,offs_t pc,const data_buffer & opcodes,const data_buffer & params)679 offs_t axc51core_disassembler::disassemble_extended_a5(std::ostream& stream, unsigned PC, offs_t pc, const data_buffer& opcodes, const data_buffer& params)
680 {
681 	uint32_t flags = 0;
682 	uint8_t prm = params.r8(PC++);
683 
684 	switch (prm)
685 	{
686 	case 0x00:
687 		util::stream_format(stream, "INCDP0");
688 		break;
689 
690 	case 0x01:
691 		util::stream_format(stream, "INCDP1");
692 		break;
693 
694 	case 0x02:
695 		util::stream_format(stream, "DECDP0");
696 		break;
697 
698 	case 0x03:
699 		util::stream_format(stream, "DECDP1");
700 		break;
701 
702 	case 0x04:
703 		util::stream_format(stream, "ADDDP0");
704 		break;
705 
706 	case 0x05:
707 		util::stream_format(stream, "ADDDP1");
708 		break;
709 
710 	case 0x06:
711 		util::stream_format(stream, "SUBDP0");
712 		break;
713 
714 	case 0x07:
715 		util::stream_format(stream, "SUBDP1");
716 		break;
717 
718 	case 0x08:
719 		util::stream_format(stream, "INC2DP0");
720 		break;
721 
722 	case 0x09:
723 		util::stream_format(stream, "INC2DP1");
724 		break;
725 
726 	case 0x0a:
727 		util::stream_format(stream, "DEC2DP0");
728 		break;
729 
730 	case 0x0b:
731 		util::stream_format(stream, "DEC2DP1");
732 		break;
733 
734 	case 0x0c:
735 		util::stream_format(stream, "ROTR8 EACC, ER8");
736 		break;
737 
738 	case 0x0d:
739 		util::stream_format(stream, "ROTL8 EACC, ER8");
740 		break;
741 
742 	case 0x0e: // ADD16
743 		return disassemble_extended_a5_0e(stream, PC, pc, opcodes, params);
744 
745 	case 0x0f: // SUB16
746 		return disassemble_extended_a5_0f(stream, PC, pc, opcodes, params);
747 
748 	case 0x10: case 0x14: case 0x18: case 0x1c:
749 	{
750 		uint8_t n = (prm & 0x0c) >> 2;
751 		util::stream_format(stream, "NOT16 ER%01x", n);
752 		break;
753 	}
754 
755 	case 0x11: case 0x15: case 0x19: case 0x1d:
756 	{
757 		uint8_t n = (prm & 0x0c) >> 2;
758 		util::stream_format(stream, "CLR16 ER%01x", n);
759 		break;
760 	}
761 
762 	case 0x12: case 0x16: case 0x1a: case 0x1e:
763 	{
764 		uint8_t n = (prm & 0x0c) >> 2;
765 		util::stream_format(stream, "INC16 ER%01x", n);
766 		break;
767 	}
768 
769 	case 0x13: case 0x17: case 0x1b: case 0x1f:
770 	{
771 		uint8_t n = (prm & 0x0c) >> 2;
772 		util::stream_format(stream, "DEC16 ER%01x", n);
773 		break;
774 	}
775 
776 	case 0x20: case 0x21: case 0x24: case 0x25: case 0x28: case 0x29: case 0x2c: case 0x2d:
777 	{
778 		uint8_t n = (prm & 0x0c) >> 2;
779 		uint8_t i = (prm & 0x01) >> 0;
780 
781 		util::stream_format(stream, "ANL16 ER%01x, EDP%01x", n, i);
782 		break;
783 	}
784 
785 	case 0x22: case 0x23: case 0x26: case 0x27: case 0x2a: case 0x2b: case 0x2e: case 0x2f:
786 	{
787 		uint8_t n = (prm & 0x0c) >> 2;
788 		uint8_t i = (prm & 0x01) >> 0;
789 
790 		util::stream_format(stream, "ANL16 EDP%01x, ER%01x", i, n);
791 		break;
792 	}
793 
794 	case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37: case 0x38: case 0x39: case 0x3a: case 0x3b: case 0x3c: case 0x3d: case 0x3e: case 0x3f:
795 	{
796 		uint8_t n = (prm & 0x0c) >> 2;
797 		uint8_t m = (prm & 0x03) >> 0;
798 
799 		util::stream_format(stream, "ANL16 ER%01x, ER%01x", n, m);
800 		break;
801 	}
802 
803 	case 0x40: case 0x41: case 0x44: case 0x45: case 0x48: case 0x49: case 0x4c: case 0x4d:
804 	{
805 		uint8_t n = (prm & 0x0c) >> 2;
806 		uint8_t i = (prm & 0x01) >> 0;
807 
808 		util::stream_format(stream, "ORL16 ER%01x, EDP%01x", n, i);
809 		break;
810 	}
811 
812 	case 0x42: case 0x43: case 0x46: case 0x47: case 0x4a: case 0x4b: case 0x4e: case 0x4f:
813 	{
814 		uint8_t n = (prm & 0x0c) >> 2;
815 		uint8_t i = (prm & 0x01) >> 0;
816 
817 		util::stream_format(stream, "ORL16 EDP%01x, ER%01x", i, n);
818 		break;
819 	}
820 
821 	case 0x50: case 0x51: case 0x52: case 0x53: case 0x54: case 0x55: case 0x56: case 0x57: case 0x58: case 0x59: case 0x5a: case 0x5b: case 0x5c: case 0x5d: case 0x5e: case 0x5f:
822 	{
823 		uint8_t n = (prm & 0x0c) >> 2;
824 		uint8_t m = (prm & 0x03) >> 0;
825 
826 		util::stream_format(stream, "ORL16 ER%01x, ER%01x", n, m);
827 		break;
828 	}
829 
830 	case 0x60: case 0x61: case 0x64: case 0x65: case 0x68: case 0x69: case 0x6c: case 0x6d:
831 	{
832 		uint8_t n = (prm & 0x0c) >> 2;
833 		uint8_t i = (prm & 0x01) >> 0;
834 
835 		util::stream_format(stream, "XRL16 ER%01x, EDP%01x", n, i);
836 		break;
837 	}
838 
839 	case 0x62: case 0x63: case 0x66: case 0x67: case 0x6a: case 0x6b: case 0x6e: case 0x6f:
840 	{
841 		uint8_t n = (prm & 0x0c) >> 2;
842 		uint8_t i = (prm & 0x01) >> 0;
843 
844 		util::stream_format(stream, "XRL16 EDP%01x, ER%01x", i, n);
845 		break;
846 	}
847 
848 	case 0x70: case 0x71: case 0x72: case 0x73: case 0x74: case 0x75: case 0x76: case 0x77: case 0x78: case 0x79: case 0x7a: case 0x7b: case 0x7c: case 0x7d: case 0x7e: case 0x7f:
849 	{
850 		uint8_t n = (prm & 0x0c) >> 2;
851 		uint8_t m = (prm & 0x03) >> 0;
852 
853 		util::stream_format(stream, "XRL16 ER%01x, ER%01x", n, m);
854 		break;
855 	}
856 
857 	case 0x80: case 0x81: case 0x84: case 0x85: case 0x88: case 0x89: case 0x8c: case 0x8d:
858 	{
859 		uint8_t n = (prm & 0x0c) >> 2;
860 		uint8_t i = (prm & 0x01) >> 0;
861 
862 		util::stream_format(stream, "MOV16 ER%01x, EDP%01x", n, i);
863 		break;
864 	}
865 
866 	case 0x82: case 0x83: case 0x86: case 0x87: case 0x8a: case 0x8b: case 0x8e: case 0x8f:
867 	{
868 		uint8_t n = (prm & 0x0c) >> 2;
869 		uint8_t i = (prm & 0x01) >> 0;
870 
871 		util::stream_format(stream, "MOV16 EDP%01x, ER%01x", i, n);
872 		break;
873 	}
874 
875 	case 0x90: case 0x91: case 0x92: case 0x93: case 0x94: case 0x95: case 0x96: case 0x97: case 0x98: case 0x99: case 0x9a: case 0x9b: case 0x9c: case 0x9d: case 0x9e: case 0x9f:
876 	{
877 		uint8_t n = (prm & 0x0c) >> 2;
878 		uint8_t m = (prm & 0x03) >> 0;
879 
880 		util::stream_format(stream, "MOV16 ER%01x, ER%01x", n, m);
881 		break;
882 	}
883 
884 	case 0xa0: case 0xa1: case 0xa2: case 0xa3: case 0xa4: case 0xa5: case 0xa6: case 0xa7: case 0xa8: case 0xa9: case 0xaa: case 0xab: case 0xac: case 0xad: case 0xae: case 0xaf:
885 	{
886 		uint8_t n = (prm & 0x0c) >> 2;
887 		uint8_t m = (prm & 0x03) >> 0;
888 
889 		util::stream_format(stream, "MUL16 ER%01x, ER%01x", n, m);
890 		break;
891 	}
892 
893 	case 0xb0: case 0xb1: case 0xb2: case 0xb3: case 0xb4: case 0xb5: case 0xb6: case 0xb7: case 0xb8: case 0xb9: case 0xba: case 0xbb: case 0xbc: case 0xbd: case 0xbe: case 0xbf:
894 	{
895 		uint8_t n = (prm & 0x0c) >> 2;
896 		uint8_t m = (prm & 0x03) >> 0;
897 
898 		util::stream_format(stream, "MULS16 ER%01x, ER%01x", n, m);
899 		break;
900 	}
901 
902 	case 0xc0: case 0xc4: case 0xc8: case 0xcc:
903 	{
904 		uint8_t n = (prm & 0x0c) >> 2;
905 		util::stream_format(stream, "ROTR16 ER%01x, ER8", n);
906 		break;
907 	}
908 
909 	case 0xc1: case 0xc5: case 0xc9: case 0xcd:
910 	{
911 		uint8_t n = (prm & 0x0c) >> 2;
912 		util::stream_format(stream, "ROTL16 ER%01x, ER8", n);
913 		break;
914 	}
915 
916 	case 0xc2: case 0xc6: case 0xca: case 0xce:
917 	{
918 		uint8_t n = (prm & 0x0c) >> 2;
919 		util::stream_format(stream, "SHIFTL ER%01x, ER8", n);
920 		break;
921 	}
922 
923 	case 0xc3: case 0xc7: case 0xcb: case 0xcf:
924 	{
925 		uint8_t n = (prm & 0x0c) >> 2;
926 		util::stream_format(stream, "SHIFTA ER%01x, ER8", n);
927 		break;
928 	}
929 
930 	case 0xd0: // ADDS16
931 		return disassemble_extended_a5_d0(stream, PC, pc, opcodes, params);
932 
933 	case 0xd1: // SUBS16
934 		return disassemble_extended_a5_d1(stream, PC, pc, opcodes, params);
935 
936 	case 0xd2: case 0xd6: case 0xda: case 0xde:
937 	{
938 		uint8_t n = (prm & 0x0c) >> 2;
939 		util::stream_format(stream, "SWAP16 ER%01x", n);
940 		break;
941 	}
942 
943 	case 0xd3: case 0xd4: case 0xd5: case 0xd7: case 0xd8: case 0xd9: case 0xdb: case 0xdc: case 0xdd: case 0xdf:
944 		util::stream_format(stream, "invalid ax208 a5 $%02X", prm);
945 		break;
946 
947 	case 0xe0: case 0xe1: case 0xe2: case 0xe3: case 0xe4: case 0xe5: case 0xe6: case 0xe7: case 0xe8: case 0xe9: case 0xea: case 0xeb: case 0xec: case 0xed: case 0xee: case 0xef:
948 		util::stream_format(stream, "invalid ax208 a5 $%02X", prm);
949 		break;
950 
951 	case 0xf0: case 0xf1: case 0xf2: case 0xf3: case 0xf4: case 0xf5: case 0xf6: case 0xf7: case 0xf8: case 0xf9: case 0xfa: case 0xfb: case 0xfc: case 0xfd: case 0xfe: case 0xff:
952 		util::stream_format(stream, "invalid ax208 a5 $%02X", prm);
953 		break;
954 
955 	default:
956 		util::stream_format(stream, "unknown ax208 a5 $%02X", prm);
957 		break;
958 	}
959 
960 	return (PC - pc) | flags | SUPPORTED;
961 }
962 
963 
disassemble_op(std::ostream & stream,unsigned PC,offs_t pc,const data_buffer & opcodes,const data_buffer & params,uint8_t op)964 offs_t axc51core_disassembler::disassemble_op(std::ostream& stream, unsigned PC, offs_t pc, const data_buffer& opcodes, const data_buffer& params, uint8_t op)
965 {
966 	uint32_t flags = 0;
967 
968 	switch (op)
969 	{
970 	case 0xa5:
971 		return disassemble_extended_a5(stream, PC, pc, opcodes, params);
972 
973 	default:
974 		return mcs51_disassembler::disassemble_op(stream, PC, pc, opcodes, params, op);
975 	}
976 
977 	return (PC - pc) | flags | SUPPORTED;
978 }
979 
980 
ax208_disassembler()981 ax208_disassembler::ax208_disassembler() : axc51core_disassembler(axc51core_names)
982 {
983 }
984 
disassemble_op_ljmp(std::ostream & stream,unsigned & PC,const data_buffer & params)985 void ax208_disassembler::disassemble_op_ljmp(std::ostream& stream, unsigned &PC, const data_buffer& params)
986 {
987 	uint16_t addr = (params.r8(PC++) << 8) & 0xff00;
988 	addr |= params.r8(PC++);
989 	if ((addr >= 0x8000) && (addr < 0xa000))
990 	{
991 		int i = 0;
992 		int lookaddr = -1;
993 		const char* lookname;
994 		do
995 		{
996 			lookaddr = bios_call_names[i].addr;
997 			lookname = bios_call_names[i].name;
998 
999 			if (lookaddr == addr)
1000 				break;
1001 
1002 			i++;
1003 		} while (lookaddr != -1);
1004 
1005 		util::stream_format(stream, "ljmp  $%04X (%s)", addr, lookname);
1006 	}
1007 	else
1008 	{
1009 		util::stream_format(stream, "ljmp  $%04X", addr);
1010 	}
1011 }
1012 
disassemble_op_lcall(std::ostream & stream,unsigned & PC,const data_buffer & params)1013 void ax208_disassembler::disassemble_op_lcall(std::ostream& stream, unsigned &PC, const data_buffer& params)
1014 {
1015 	uint16_t addr = (params.r8(PC++)<<8) & 0xff00;
1016 	addr|= params.r8(PC++);
1017 	if ((addr >= 0x8000) && (addr < 0xa000))
1018 	{
1019 		int i = 0;
1020 		int lookaddr = -1;
1021 		const char* lookname;
1022 		do
1023 		{
1024 			lookaddr = bios_call_names[i].addr;
1025 			lookname = bios_call_names[i].name;
1026 
1027 			if (lookaddr == addr)
1028 				break;
1029 
1030 			i++;
1031 		} while (lookaddr != -1);
1032 
1033 		util::stream_format(stream, "lcall $%04X (%s)", addr, lookname);
1034 	}
1035 	else
1036 	{
1037 		util::stream_format(stream, "lcall $%04X", addr);
1038 	}
1039 }
1040