comparison 68kinst.c @ 2133:8554751f17b5

Remove use of get_native_pointer in 68K instruction decoding in preparation for word RAM interleaving
author Michael Pavone <pavone@retrodev.com>
date Thu, 17 Mar 2022 22:41:42 -0700
parents dc1eab3ec092
children 53411df7fc71
comparison
equal deleted inserted replaced
2132:7451f970ee66 2133:8554751f17b5
15 uint32_t sign_extend8(uint32_t val) 15 uint32_t sign_extend8(uint32_t val)
16 { 16 {
17 return (val & 0x80) ? val | 0xFFFFFF00 : val; 17 return (val & 0x80) ? val | 0xFFFFFF00 : val;
18 } 18 }
19 19
20 uint16_t *m68k_decode_op_ex(uint16_t *cur, uint8_t mode, uint8_t reg, uint8_t size, m68k_op_info *dst) 20 #define INVALID_ADDRESS 0xFFFFFFFF
21
22 uint32_t m68k_decode_op_ex(uint16_t opcode, uint32_t address, m68k_fetch_fun fetch, void *data, uint8_t mode, uint8_t reg, uint8_t size, m68k_op_info *dst)
21 { 23 {
22 uint16_t ext, tmp; 24 uint16_t ext, tmp;
23 dst->addr_mode = mode; 25 dst->addr_mode = mode;
24 switch(mode) 26 switch(mode)
25 { 27 {
29 case MODE_AREG_POSTINC: 31 case MODE_AREG_POSTINC:
30 case MODE_AREG_PREDEC: 32 case MODE_AREG_PREDEC:
31 dst->params.regs.pri = reg; 33 dst->params.regs.pri = reg;
32 break; 34 break;
33 case MODE_AREG_DISPLACE: 35 case MODE_AREG_DISPLACE:
34 ext = *(++cur); 36 ext = fetch(address, data);
37 address += 2;
35 dst->params.regs.pri = reg; 38 dst->params.regs.pri = reg;
36 dst->params.regs.displacement = sign_extend16(ext); 39 dst->params.regs.displacement = sign_extend16(ext);
37 break; 40 break;
38 case MODE_AREG_INDEX_MEM: 41 case MODE_AREG_INDEX_MEM:
39 dst->params.regs.pri = reg; 42 dst->params.regs.pri = reg;
40 ext = *(++cur); 43 ext = fetch(address, data);
44 address += 2;
41 dst->params.regs.sec = ext >> 11;//includes areg/dreg bit, reg num and word/long bit 45 dst->params.regs.sec = ext >> 11;//includes areg/dreg bit, reg num and word/long bit
42 #ifdef M68020 46 #ifdef M68020
43 dst->params.regs.scale = ext >> 9 & 3; 47 dst->params.regs.scale = ext >> 9 & 3;
44 if (ext & 0x100) 48 if (ext & 0x100)
45 { 49 {
46 dst->params.regs.disp_sizes = ext >> 4 & 3; 50 dst->params.regs.disp_sizes = ext >> 4 & 3;
47 switch (dst->params.regs.disp_sizes) 51 switch (dst->params.regs.disp_sizes)
48 { 52 {
49 case 0: 53 case 0:
50 //reserved 54 //reserved
51 return NULL; 55 return INVALID_ADDRESS;
52 case 1: 56 case 1:
53 dst->params.regs.displacement = 0; 57 dst->params.regs.displacement = 0;
54 break; 58 break;
55 case 2: 59 case 2:
56 dst->params.regs.displacement = sign_extend16(*(cur++)); 60 dst->params.regs.displacement = sign_extend16(fetch(address, data));
61 address += 2;
57 break; 62 break;
58 case 3: 63 case 3:
59 tmp = *(cur++); 64 tmp = fetch(address, data);
60 dst->params.regs.displacement = tmp << 16 | *(cur++); 65 address += 2;
66 dst->params.regs.displacement = tmp << 16 | fetch(address, data);
67 address += 2;
61 break; 68 break;
62 } 69 }
63 if (ext & 0x3) 70 if (ext & 0x3)
64 { 71 {
65 //memory indirect 72 //memory indirect
87 dst->params.regs.disp_sizes |= ext << 4 & 0x30; 94 dst->params.regs.disp_sizes |= ext << 4 & 0x30;
88 switch (ext & 0x3) 95 switch (ext & 0x3)
89 { 96 {
90 case 0: 97 case 0:
91 //reserved 98 //reserved
92 return NULL; 99 return INVALID_ADDRESS;
93 case 1: 100 case 1:
94 dst->params.regs.outer_disp = 0; 101 dst->params.regs.outer_disp = 0;
95 break; 102 break;
96 case 2: 103 case 2:
97 dst->params.regs.outer_disp = sign_extend16(*(cur++)); 104 dst->params.regs.outer_disp = sign_extend16(fetch(address, data));
105 address += 2;
98 break; 106 break;
99 case 3: 107 case 3:
100 tmp = *(cur++); 108 tmp = fetch(address, data);
101 dst->params.regs.outer_disp = tmp << 16 | *(cur++); 109 address += 2;
110 dst->params.regs.outer_disp = tmp << 16 | fetch(address, data);
111 address += 2;
102 break; 112 break;
103 } 113 }
104 } else { 114 } else {
105 switch (ext >> 6 & 3) 115 switch (ext >> 6 & 3)
106 { 116 {
129 case MODE_PC_INDIRECT_ABS_IMMED: 139 case MODE_PC_INDIRECT_ABS_IMMED:
130 switch(reg) 140 switch(reg)
131 { 141 {
132 case 0: 142 case 0:
133 dst->addr_mode = MODE_ABSOLUTE_SHORT; 143 dst->addr_mode = MODE_ABSOLUTE_SHORT;
134 ext = *(++cur); 144 ext = fetch(address, data);
145 address += 2;
135 dst->params.immed = sign_extend16(ext); 146 dst->params.immed = sign_extend16(ext);
136 break; 147 break;
137 case 1: 148 case 1:
138 dst->addr_mode = MODE_ABSOLUTE; 149 dst->addr_mode = MODE_ABSOLUTE;
139 ext = *(++cur); 150 ext = fetch(address, data);
140 dst->params.immed = ext << 16 | *(++cur); 151 address += 2;
152 dst->params.immed = ext << 16 | fetch(address, data);
153 address += 2;
141 break; 154 break;
142 case 3: 155 case 3:
143 ext = *(++cur); 156 ext = fetch(address, data);
157 address += 2;
144 dst->params.regs.sec = ext >> 11;//includes areg/dreg bit, reg num and word/long bit 158 dst->params.regs.sec = ext >> 11;//includes areg/dreg bit, reg num and word/long bit
145 #ifdef M68020 159 #ifdef M68020
146 dst->params.regs.scale = ext >> 9 & 3; 160 dst->params.regs.scale = ext >> 9 & 3;
147 if (ext & 0x100) 161 if (ext & 0x100)
148 { 162 {
149 dst->params.regs.disp_sizes = ext >> 4 & 3; 163 dst->params.regs.disp_sizes = ext >> 4 & 3;
150 switch (dst->params.regs.disp_sizes) 164 switch (dst->params.regs.disp_sizes)
151 { 165 {
152 case 0: 166 case 0:
153 //reserved 167 //reserved
154 return NULL; 168 return INVALID_ADDRESS;
155 case 1: 169 case 1:
156 dst->params.regs.displacement = 0; 170 dst->params.regs.displacement = 0;
157 break; 171 break;
158 case 2: 172 case 2:
159 dst->params.regs.displacement = sign_extend16(*(cur++)); 173 dst->params.regs.displacement = sign_extend16(fetch(address, data));
174 address += 2;
160 break; 175 break;
161 case 3: 176 case 3:
162 tmp = *(cur++); 177 tmp = *(cur++);
163 dst->params.regs.displacement = tmp << 16 | *(cur++); 178 dst->params.regs.displacement = tmp << 16 | fetch(address, data);
179 address += 2;
164 break; 180 break;
165 } 181 }
166 if (ext & 0x3) 182 if (ext & 0x3)
167 { 183 {
168 //memory indirect 184 //memory indirect
190 dst->params.regs.disp_sizes |= ext << 4 & 0x30; 206 dst->params.regs.disp_sizes |= ext << 4 & 0x30;
191 switch (ext & 0x3) 207 switch (ext & 0x3)
192 { 208 {
193 case 0: 209 case 0:
194 //reserved 210 //reserved
195 return NULL; 211 return INVALID_ADDRESS;
196 case 1: 212 case 1:
197 dst->params.regs.outer_disp = 0; 213 dst->params.regs.outer_disp = 0;
198 break; 214 break;
199 case 2: 215 case 2:
200 dst->params.regs.outer_disp = sign_extend16(*(cur++)); 216 dst->params.regs.outer_disp = sign_extend16(fetch(address, data));
217 address += 2;
201 break; 218 break;
202 case 3: 219 case 3:
203 tmp = *(cur++); 220 tmp = fetch(address, data);
204 dst->params.regs.outer_disp = tmp << 16 | *(cur++); 221 address += 2;
222 dst->params.regs.outer_disp = tmp << 16 | fetch(address, data);
223 address += 2;
205 break; 224 break;
206 } 225 }
207 } else { 226 } else {
208 switch (ext >> 6 & 3) 227 switch (ext >> 6 & 3)
209 { 228 {
229 } 248 }
230 #endif 249 #endif
231 break; 250 break;
232 case 2: 251 case 2:
233 dst->addr_mode = MODE_PC_DISPLACE; 252 dst->addr_mode = MODE_PC_DISPLACE;
234 ext = *(++cur); 253 ext = fetch(address, data);
254 address += 2;
235 dst->params.regs.displacement = sign_extend16(ext); 255 dst->params.regs.displacement = sign_extend16(ext);
236 break; 256 break;
237 case 4: 257 case 4:
238 dst->addr_mode = MODE_IMMEDIATE; 258 dst->addr_mode = MODE_IMMEDIATE;
239 ext = *(++cur); 259 ext = fetch(address, data);
260 address += 2;
240 switch (size) 261 switch (size)
241 { 262 {
242 case OPSIZE_BYTE: 263 case OPSIZE_BYTE:
243 dst->params.immed = ext & 0xFF; 264 dst->params.immed = ext & 0xFF;
244 break; 265 break;
245 case OPSIZE_WORD: 266 case OPSIZE_WORD:
246 dst->params.immed = ext; 267 dst->params.immed = ext;
247 break; 268 break;
248 case OPSIZE_LONG: 269 case OPSIZE_LONG:
249 dst->params.immed = ext << 16 | *(++cur); 270 dst->params.immed = ext << 16 | fetch(address, data);
271 address += 2;
250 break; 272 break;
251 } 273 }
252 break; 274 break;
253 default: 275 default:
254 return NULL; 276 return INVALID_ADDRESS;
255 } 277 }
256 break; 278 break;
257 } 279 }
258 return cur; 280 return address;
259 } 281 }
260 282
261 uint8_t m68k_valid_immed_dst(m68k_op_info *dst) 283 uint8_t m68k_valid_immed_dst(m68k_op_info *dst)
262 { 284 {
263 if (dst->addr_mode == MODE_AREG || dst->addr_mode == MODE_IMMEDIATE) { 285 if (dst->addr_mode == MODE_AREG || dst->addr_mode == MODE_IMMEDIATE) {
288 return 0; 310 return 0;
289 } 311 }
290 return m68k_valid_immed_limited_dst(dst); 312 return m68k_valid_immed_limited_dst(dst);
291 } 313 }
292 314
293 uint16_t *m68k_decode_op(uint16_t *cur, uint8_t size, m68k_op_info *dst) 315 uint32_t m68k_decode_op(uint16_t opcode, uint32_t address, m68k_fetch_fun fetch, void *data, uint8_t size, m68k_op_info *dst)
294 { 316 {
295 uint8_t mode = (*cur >> 3) & 0x7; 317 uint8_t mode = (opcode >> 3) & 0x7;
296 uint8_t reg = *cur & 0x7; 318 uint8_t reg = opcode & 0x7;
297 return m68k_decode_op_ex(cur, mode, reg, size, dst); 319 return m68k_decode_op_ex(opcode, address, fetch, data, mode, reg, size, dst);
298 } 320 }
299 321
300 void m68k_decode_cond(uint16_t op, m68kinst * decoded) 322 void m68k_decode_cond(uint16_t op, m68kinst * decoded)
301 { 323 {
302 decoded->extra.cond = (op >> 0x8) & 0xF; 324 decoded->extra.cond = (op >> 0x8) & 0xF;
305 uint8_t m68k_reg_quick_field(uint16_t op) 327 uint8_t m68k_reg_quick_field(uint16_t op)
306 { 328 {
307 return (op >> 9) & 0x7; 329 return (op >> 9) & 0x7;
308 } 330 }
309 331
310 uint16_t * m68k_decode(uint16_t * istream, m68kinst * decoded, uint32_t address) 332 uint32_t m68k_decode(m68k_fetch_fun fetch, void *data, m68kinst * decoded, uint32_t address)
311 { 333 {
312 uint16_t *start = istream; 334 uint32_t start_address = address;
313 uint8_t optype = *istream >> 12; 335 uint16_t opcode = fetch(address, data);
336 address += 2;
337 uint8_t optype = opcode >> 12;
314 uint8_t size; 338 uint8_t size;
315 uint8_t reg; 339 uint8_t reg;
316 uint8_t opmode; 340 uint8_t opmode;
317 uint32_t immed; 341 uint32_t immed;
318 decoded->op = M68K_INVALID; 342 decoded->op = M68K_INVALID;
319 decoded->src.addr_mode = decoded->dst.addr_mode = MODE_UNUSED; 343 decoded->src.addr_mode = decoded->dst.addr_mode = MODE_UNUSED;
320 decoded->variant = VAR_NORMAL; 344 decoded->variant = VAR_NORMAL;
321 decoded->address = address; 345 decoded->address = start_address;
322 switch(optype) 346 switch(optype)
323 { 347 {
324 case BIT_MOVEP_IMMED: 348 case BIT_MOVEP_IMMED:
325 if ((*istream & 0x138) == 0x108) { 349 if ((opcode & 0x138) == 0x108) {
326 //MOVEP 350 //MOVEP
327 decoded->op = M68K_MOVEP; 351 decoded->op = M68K_MOVEP;
328 decoded->extra.size = *istream & 0x40 ? OPSIZE_LONG : OPSIZE_WORD; 352 decoded->extra.size = opcode & 0x40 ? OPSIZE_LONG : OPSIZE_WORD;
329 if (*istream & 0x80) { 353 if (opcode & 0x80) {
330 //memory dest 354 //memory dest
331 decoded->src.addr_mode = MODE_REG; 355 decoded->src.addr_mode = MODE_REG;
332 decoded->src.params.regs.pri = m68k_reg_quick_field(*istream); 356 decoded->src.params.regs.pri = m68k_reg_quick_field(opcode);
333 decoded->dst.addr_mode = MODE_AREG_DISPLACE; 357 decoded->dst.addr_mode = MODE_AREG_DISPLACE;
334 decoded->dst.params.regs.pri = *istream & 0x7; 358 decoded->dst.params.regs.pri = opcode & 0x7;
335 decoded->dst.params.regs.displacement = *(++istream); 359 decoded->dst.params.regs.displacement = fetch(address, data);
360 address += 2;
336 } else { 361 } else {
337 //memory source 362 //memory source
338 decoded->dst.addr_mode = MODE_REG; 363 decoded->dst.addr_mode = MODE_REG;
339 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); 364 decoded->dst.params.regs.pri = m68k_reg_quick_field(opcode);
340 decoded->src.addr_mode = MODE_AREG_DISPLACE; 365 decoded->src.addr_mode = MODE_AREG_DISPLACE;
341 decoded->src.params.regs.pri = *istream & 0x7; 366 decoded->src.params.regs.pri = opcode & 0x7;
342 decoded->src.params.regs.displacement = *(++istream); 367 decoded->src.params.regs.displacement = fetch(address, data);
343 } 368 address += 2;
344 } else if (*istream & 0x100) { 369 }
370 } else if (opcode & 0x100) {
345 //BTST, BCHG, BCLR, BSET 371 //BTST, BCHG, BCLR, BSET
346 switch ((*istream >> 6) & 0x3) 372 switch ((opcode >> 6) & 0x3)
347 { 373 {
348 case 0: 374 case 0:
349 decoded->op = M68K_BTST; 375 decoded->op = M68K_BTST;
350 break; 376 break;
351 case 1: 377 case 1:
357 case 3: 383 case 3:
358 decoded->op = M68K_BSET; 384 decoded->op = M68K_BSET;
359 break; 385 break;
360 } 386 }
361 decoded->src.addr_mode = MODE_REG; 387 decoded->src.addr_mode = MODE_REG;
362 decoded->src.params.regs.pri = m68k_reg_quick_field(*istream); 388 decoded->src.params.regs.pri = m68k_reg_quick_field(opcode);
363 decoded->extra.size = OPSIZE_BYTE; 389 decoded->extra.size = OPSIZE_BYTE;
364 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->dst)); 390 address = m68k_decode_op(opcode, address, fetch, data, decoded->extra.size, &(decoded->dst));
365 if ( 391 if (
366 !istream || decoded->dst.addr_mode == MODE_AREG 392 address == INVALID_ADDRESS || decoded->dst.addr_mode == MODE_AREG
367 || (decoded->op != M68K_BTST && !m68k_valid_immed_limited_dst(&decoded->dst)) 393 || (decoded->op != M68K_BTST && !m68k_valid_immed_limited_dst(&decoded->dst))
368 ) { 394 ) {
369 decoded->op = M68K_INVALID; 395 decoded->op = M68K_INVALID;
370 break; 396 break;
371 } 397 }
372 if (decoded->dst.addr_mode == MODE_REG) { 398 if (decoded->dst.addr_mode == MODE_REG) {
373 decoded->extra.size = OPSIZE_LONG; 399 decoded->extra.size = OPSIZE_LONG;
374 } 400 }
375 } else if ((*istream & 0xF00) == 0x800) { 401 } else if ((opcode & 0xF00) == 0x800) {
376 //BTST, BCHG, BCLR, BSET 402 //BTST, BCHG, BCLR, BSET
377 switch ((*istream >> 6) & 0x3) 403 switch ((opcode >> 6) & 0x3)
378 { 404 {
379 case 0: 405 case 0:
380 decoded->op = M68K_BTST; 406 decoded->op = M68K_BTST;
381 break; 407 break;
382 case 1: 408 case 1:
387 break; 413 break;
388 case 3: 414 case 3:
389 decoded->op = M68K_BSET; 415 decoded->op = M68K_BSET;
390 break; 416 break;
391 } 417 }
392 opmode = (*istream >> 3) & 0x7; 418 opmode = (opcode >> 3) & 0x7;
393 reg = *istream & 0x7; 419 reg = opcode & 0x7;
394 decoded->src.addr_mode = MODE_IMMEDIATE_WORD; 420 decoded->src.addr_mode = MODE_IMMEDIATE_WORD;
395 decoded->src.params.immed = *(++istream) & 0xFF; 421 decoded->src.params.immed = fetch(address, data) & 0xFF;
422 address += 2;
396 decoded->extra.size = OPSIZE_BYTE; 423 decoded->extra.size = OPSIZE_BYTE;
397 istream = m68k_decode_op_ex(istream, opmode, reg, decoded->extra.size, &(decoded->dst)); 424 address = m68k_decode_op_ex(opcode, address, fetch, data, opmode, reg, decoded->extra.size, &(decoded->dst));
398 if ( 425 if (
399 !istream || !m68k_valid_immed_dst(&decoded->dst) 426 address == INVALID_ADDRESS || !m68k_valid_immed_dst(&decoded->dst)
400 || (decoded->op != M68K_BTST && !m68k_valid_immed_limited_dst(&decoded->dst)) 427 || (decoded->op != M68K_BTST && !m68k_valid_immed_limited_dst(&decoded->dst))
401 ) { 428 ) {
402 decoded->op = M68K_INVALID; 429 decoded->op = M68K_INVALID;
403 break; 430 break;
404 } 431 }
405 if (decoded->dst.addr_mode == MODE_REG) { 432 if (decoded->dst.addr_mode == MODE_REG) {
406 decoded->extra.size = OPSIZE_LONG; 433 decoded->extra.size = OPSIZE_LONG;
407 } 434 }
408 } else if ((*istream & 0xC0) == 0xC0) { 435 } else if ((opcode & 0xC0) == 0xC0) {
409 #ifdef M68020 436 #ifdef M68020
410 //CMP2, CHK2, CAS, CAS2, RTM, CALLM 437 //CMP2, CHK2, CAS, CAS2, RTM, CALLM
411 #endif 438 #endif
412 } else { 439 } else {
413 switch ((*istream >> 9) & 0x7) 440 switch ((opcode >> 9) & 0x7)
414 { 441 {
415 case 0: 442 case 0:
416 if ((*istream & 0xFF) == 0x3C) { 443 if ((opcode & 0xFF) == 0x3C) {
417 decoded->op = M68K_ORI_CCR; 444 decoded->op = M68K_ORI_CCR;
418 decoded->extra.size = OPSIZE_BYTE; 445 decoded->extra.size = OPSIZE_BYTE;
419 decoded->src.addr_mode = MODE_IMMEDIATE; 446 decoded->src.addr_mode = MODE_IMMEDIATE;
420 decoded->src.params.immed = *(++istream) & 0xFF; 447 decoded->src.params.immed = fetch(address, data) & 0xFF;
421 } else if((*istream & 0xFF) == 0x7C) { 448 address += 2;
449 } else if((opcode & 0xFF) == 0x7C) {
422 decoded->op = M68K_ORI_SR; 450 decoded->op = M68K_ORI_SR;
423 decoded->extra.size = OPSIZE_WORD; 451 decoded->extra.size = OPSIZE_WORD;
424 decoded->src.addr_mode = MODE_IMMEDIATE; 452 decoded->src.addr_mode = MODE_IMMEDIATE;
425 decoded->src.params.immed = *(++istream); 453 decoded->src.params.immed = fetch(address, data);
454 address += 2;
426 } else { 455 } else {
427 decoded->op = M68K_OR; 456 decoded->op = M68K_OR;
428 decoded->variant = VAR_IMMEDIATE; 457 decoded->variant = VAR_IMMEDIATE;
429 decoded->src.addr_mode = MODE_IMMEDIATE; 458 decoded->src.addr_mode = MODE_IMMEDIATE;
430 decoded->extra.size = size = (*istream >> 6) & 3; 459 decoded->extra.size = size = (opcode >> 6) & 3;
431 reg = *istream & 0x7; 460 reg = opcode & 0x7;
432 opmode = (*istream >> 3) & 0x7; 461 opmode = (opcode >> 3) & 0x7;
433 switch (size) 462 switch (size)
434 { 463 {
435 case OPSIZE_BYTE: 464 case OPSIZE_BYTE:
436 decoded->src.params.immed = *(++istream) & 0xFF; 465 decoded->src.params.immed = fetch(address, data) & 0xFF;
466 address += 2;
437 break; 467 break;
438 case OPSIZE_WORD: 468 case OPSIZE_WORD:
439 decoded->src.params.immed = *(++istream); 469 decoded->src.params.immed = fetch(address, data);
470 address += 2;
440 break; 471 break;
441 case OPSIZE_LONG: 472 case OPSIZE_LONG:
442 immed = *(++istream); 473 immed = fetch(address, data);
443 decoded->src.params.immed = immed << 16 | *(++istream); 474 address += 2;
475 decoded->src.params.immed = immed << 16 | fetch(address, data);
476 address += 2;
444 break; 477 break;
445 } 478 }
446 istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst)); 479 address = m68k_decode_op_ex(opcode, address, fetch, data, opmode, reg, size, &(decoded->dst));
447 if (!istream || !m68k_valid_immed_limited_dst(&(decoded->dst))) { 480 if (address == INVALID_ADDRESS || !m68k_valid_immed_limited_dst(&(decoded->dst))) {
448 decoded->op = M68K_INVALID; 481 decoded->op = M68K_INVALID;
449 break; 482 break;
450 } 483 }
451 } 484 }
452 break; 485 break;
453 case 1: 486 case 1:
454 //ANDI, ANDI to CCR, ANDI to SR 487 //ANDI, ANDI to CCR, ANDI to SR
455 if ((*istream & 0xFF) == 0x3C) { 488 if ((opcode & 0xFF) == 0x3C) {
456 decoded->op = M68K_ANDI_CCR; 489 decoded->op = M68K_ANDI_CCR;
457 decoded->extra.size = OPSIZE_BYTE; 490 decoded->extra.size = OPSIZE_BYTE;
458 decoded->src.addr_mode = MODE_IMMEDIATE; 491 decoded->src.addr_mode = MODE_IMMEDIATE;
459 decoded->src.params.immed = *(++istream) & 0xFF; 492 decoded->src.params.immed = fetch(address, data) & 0xFF;
460 } else if((*istream & 0xFF) == 0x7C) { 493 address += 2;
494 } else if((opcode & 0xFF) == 0x7C) {
461 decoded->op = M68K_ANDI_SR; 495 decoded->op = M68K_ANDI_SR;
462 decoded->extra.size = OPSIZE_WORD; 496 decoded->extra.size = OPSIZE_WORD;
463 decoded->src.addr_mode = MODE_IMMEDIATE; 497 decoded->src.addr_mode = MODE_IMMEDIATE;
464 decoded->src.params.immed = *(++istream); 498 decoded->src.params.immed = fetch(address, data);
499 address += 2;
465 } else { 500 } else {
466 decoded->op = M68K_AND; 501 decoded->op = M68K_AND;
467 decoded->variant = VAR_IMMEDIATE; 502 decoded->variant = VAR_IMMEDIATE;
468 decoded->src.addr_mode = MODE_IMMEDIATE; 503 decoded->src.addr_mode = MODE_IMMEDIATE;
469 decoded->extra.size = size = (*istream >> 6) & 3; 504 decoded->extra.size = size = (opcode >> 6) & 3;
470 reg = *istream & 0x7; 505 reg = opcode & 0x7;
471 opmode = (*istream >> 3) & 0x7; 506 opmode = (opcode >> 3) & 0x7;
472 switch (size) 507 switch (size)
473 { 508 {
474 case OPSIZE_BYTE: 509 case OPSIZE_BYTE:
475 decoded->src.params.immed = *(++istream) & 0xFF; 510 decoded->src.params.immed = fetch(address, data) & 0xFF;
511 address += 2;
476 break; 512 break;
477 case OPSIZE_WORD: 513 case OPSIZE_WORD:
478 decoded->src.params.immed = *(++istream); 514 decoded->src.params.immed = fetch(address, data);
515 address += 2;
479 break; 516 break;
480 case OPSIZE_LONG: 517 case OPSIZE_LONG:
481 immed = *(++istream); 518 immed = fetch(address, data);
482 decoded->src.params.immed = immed << 16 | *(++istream); 519 address += 2;
520 decoded->src.params.immed = immed << 16 | fetch(address, data);
521 address += 2;
483 break; 522 break;
484 } 523 }
485 istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst)); 524 address = m68k_decode_op_ex(opcode, address, fetch, data, opmode, reg, size, &(decoded->dst));
486 if (!istream || !m68k_valid_immed_limited_dst(&(decoded->dst))) { 525 if (address == INVALID_ADDRESS || !m68k_valid_immed_limited_dst(&(decoded->dst))) {
487 decoded->op = M68K_INVALID; 526 decoded->op = M68K_INVALID;
488 break; 527 break;
489 } 528 }
490 } 529 }
491 break; 530 break;
492 case 2: 531 case 2:
493 decoded->op = M68K_SUB; 532 decoded->op = M68K_SUB;
494 decoded->variant = VAR_IMMEDIATE; 533 decoded->variant = VAR_IMMEDIATE;
495 decoded->src.addr_mode = MODE_IMMEDIATE; 534 decoded->src.addr_mode = MODE_IMMEDIATE;
496 decoded->extra.size = size = (*istream >> 6) & 3; 535 decoded->extra.size = size = (opcode >> 6) & 3;
497 reg = *istream & 0x7; 536 reg = opcode & 0x7;
498 opmode = (*istream >> 3) & 0x7; 537 opmode = (opcode >> 3) & 0x7;
499 switch (size) 538 switch (size)
500 { 539 {
501 case OPSIZE_BYTE: 540 case OPSIZE_BYTE:
502 decoded->src.params.immed = *(++istream) & 0xFF; 541 decoded->src.params.immed = fetch(address, data) & 0xFF;
542 address += 2;
503 break; 543 break;
504 case OPSIZE_WORD: 544 case OPSIZE_WORD:
505 decoded->src.params.immed = *(++istream); 545 decoded->src.params.immed = fetch(address, data);
546 address += 2;
506 break; 547 break;
507 case OPSIZE_LONG: 548 case OPSIZE_LONG:
508 immed = *(++istream); 549 immed = fetch(address, data);
509 decoded->src.params.immed = immed << 16 | *(++istream); 550 address += 2;
510 break; 551 decoded->src.params.immed = immed << 16 | fetch(address, data);
511 } 552 address += 2;
512 istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst)); 553 break;
513 if (!istream || !m68k_valid_immed_limited_dst(&(decoded->dst))) { 554 }
555 address = m68k_decode_op_ex(opcode, address, fetch, data, opmode, reg, size, &(decoded->dst));
556 if (address == INVALID_ADDRESS || !m68k_valid_immed_limited_dst(&(decoded->dst))) {
514 decoded->op = M68K_INVALID; 557 decoded->op = M68K_INVALID;
515 break; 558 break;
516 } 559 }
517 break; 560 break;
518 case 3: 561 case 3:
519 decoded->op = M68K_ADD; 562 decoded->op = M68K_ADD;
520 decoded->variant = VAR_IMMEDIATE; 563 decoded->variant = VAR_IMMEDIATE;
521 decoded->src.addr_mode = MODE_IMMEDIATE; 564 decoded->src.addr_mode = MODE_IMMEDIATE;
522 decoded->extra.size = size = (*istream >> 6) & 3; 565 decoded->extra.size = size = (opcode >> 6) & 3;
523 reg = *istream & 0x7; 566 reg = opcode & 0x7;
524 opmode = (*istream >> 3) & 0x7; 567 opmode = (opcode >> 3) & 0x7;
525 switch (size) 568 switch (size)
526 { 569 {
527 case OPSIZE_BYTE: 570 case OPSIZE_BYTE:
528 decoded->src.params.immed = *(++istream) & 0xFF; 571 decoded->src.params.immed = fetch(address, data) & 0xFF;
572 address += 2;
529 break; 573 break;
530 case OPSIZE_WORD: 574 case OPSIZE_WORD:
531 decoded->src.params.immed = *(++istream); 575 decoded->src.params.immed = fetch(address, data);
576 address += 2;
532 break; 577 break;
533 case OPSIZE_LONG: 578 case OPSIZE_LONG:
534 immed = *(++istream); 579 immed = fetch(address, data);
535 decoded->src.params.immed = immed << 16 | *(++istream); 580 address += 2;
536 break; 581 decoded->src.params.immed = immed << 16 | fetch(address, data);
537 } 582 address += 2;
538 istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst)); 583 break;
539 if (!istream || !m68k_valid_immed_limited_dst(&(decoded->dst))) { 584 }
585 address = m68k_decode_op_ex(opcode, address, fetch, data, opmode, reg, size, &(decoded->dst));
586 if (address == INVALID_ADDRESS || !m68k_valid_immed_limited_dst(&(decoded->dst))) {
540 decoded->op = M68K_INVALID; 587 decoded->op = M68K_INVALID;
541 break; 588 break;
542 } 589 }
543 break; 590 break;
544 case 4: 591 case 4:
545 //BTST, BCHG, BCLR, BSET 592 //BTST, BCHG, BCLR, BSET
546 //Seems like this should be unnecessary since bit instructions are explicitly handled above 593 //Seems like this should be unnecessary since bit instructions are explicitly handled above
547 //Possible this is redundant or the case above is overly restrictive 594 //Possible this is redundant or the case above is overly restrictive
548 //TODO: Investigate whether this can be removed 595 //TODO: Investigate whether this can be removed
549 switch ((*istream >> 6) & 0x3) 596 switch ((opcode >> 6) & 0x3)
550 { 597 {
551 case 0: 598 case 0:
552 decoded->op = M68K_BTST; 599 decoded->op = M68K_BTST;
553 break; 600 break;
554 case 1: 601 case 1:
560 case 3: 607 case 3:
561 decoded->op = M68K_BSET; 608 decoded->op = M68K_BSET;
562 break; 609 break;
563 } 610 }
564 decoded->src.addr_mode = MODE_IMMEDIATE_WORD; 611 decoded->src.addr_mode = MODE_IMMEDIATE_WORD;
565 decoded->src.params.immed = *(++istream) & 0xFF; 612 decoded->src.params.immed = fetch(address, data) & 0xFF;
566 istream = m68k_decode_op(istream, OPSIZE_BYTE, &(decoded->dst)); 613 address += 2;
614 address = m68k_decode_op(opcode, address, fetch, data, OPSIZE_BYTE, &(decoded->dst));
567 if ( 615 if (
568 !istream || !m68k_valid_immed_dst(&decoded->dst) 616 address == INVALID_ADDRESS || !m68k_valid_immed_dst(&decoded->dst)
569 || (decoded->op != M68K_BTST && !m68k_valid_immed_limited_dst(&decoded->dst)) 617 || (decoded->op != M68K_BTST && !m68k_valid_immed_limited_dst(&decoded->dst))
570 ) { 618 ) {
571 decoded->op = M68K_INVALID; 619 decoded->op = M68K_INVALID;
572 break; 620 break;
573 } 621 }
574 break; 622 break;
575 case 5: 623 case 5:
576 //EORI, EORI to CCR, EORI to SR 624 //EORI, EORI to CCR, EORI to SR
577 if ((*istream & 0xFF) == 0x3C) { 625 if ((opcode & 0xFF) == 0x3C) {
578 decoded->op = M68K_EORI_CCR; 626 decoded->op = M68K_EORI_CCR;
579 decoded->extra.size = OPSIZE_BYTE; 627 decoded->extra.size = OPSIZE_BYTE;
580 decoded->src.addr_mode = MODE_IMMEDIATE; 628 decoded->src.addr_mode = MODE_IMMEDIATE;
581 decoded->src.params.immed = *(++istream) & 0xFF; 629 decoded->src.params.immed = fetch(address, data) & 0xFF;
582 } else if((*istream & 0xFF) == 0x7C) { 630 address += 2;
631 } else if((opcode & 0xFF) == 0x7C) {
583 decoded->op = M68K_EORI_SR; 632 decoded->op = M68K_EORI_SR;
584 decoded->extra.size = OPSIZE_WORD; 633 decoded->extra.size = OPSIZE_WORD;
585 decoded->src.addr_mode = MODE_IMMEDIATE; 634 decoded->src.addr_mode = MODE_IMMEDIATE;
586 decoded->src.params.immed = *(++istream); 635 decoded->src.params.immed = fetch(address, data);
636 address += 2;
587 } else { 637 } else {
588 decoded->op = M68K_EOR; 638 decoded->op = M68K_EOR;
589 decoded->variant = VAR_IMMEDIATE; 639 decoded->variant = VAR_IMMEDIATE;
590 decoded->src.addr_mode = MODE_IMMEDIATE; 640 decoded->src.addr_mode = MODE_IMMEDIATE;
591 decoded->extra.size = size = (*istream >> 6) & 3; 641 decoded->extra.size = size = (opcode >> 6) & 3;
592 reg = *istream & 0x7; 642 reg = opcode & 0x7;
593 opmode = (*istream >> 3) & 0x7; 643 opmode = (opcode >> 3) & 0x7;
594 switch (size) 644 switch (size)
595 { 645 {
596 case OPSIZE_BYTE: 646 case OPSIZE_BYTE:
597 decoded->src.params.immed = *(++istream) & 0xFF; 647 decoded->src.params.immed = fetch(address, data) & 0xFF;
648 address += 2;
598 break; 649 break;
599 case OPSIZE_WORD: 650 case OPSIZE_WORD:
600 decoded->src.params.immed = *(++istream); 651 decoded->src.params.immed = fetch(address, data);
652 address += 2;
601 break; 653 break;
602 case OPSIZE_LONG: 654 case OPSIZE_LONG:
603 immed = *(++istream); 655 immed = fetch(address, data);
604 decoded->src.params.immed = immed << 16 | *(++istream); 656 address += 2;
657 decoded->src.params.immed = immed << 16 | fetch(address, data);
658 address += 2;
605 break; 659 break;
606 } 660 }
607 istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst)); 661 address = m68k_decode_op_ex(opcode, address, fetch, data, opmode, reg, size, &(decoded->dst));
608 if (!istream || !m68k_valid_immed_limited_dst(&(decoded->dst))) { 662 if (address == INVALID_ADDRESS || !m68k_valid_immed_limited_dst(&(decoded->dst))) {
609 decoded->op = M68K_INVALID; 663 decoded->op = M68K_INVALID;
610 break; 664 break;
611 } 665 }
612 } 666 }
613 break; 667 break;
614 case 6: 668 case 6:
615 decoded->op = M68K_CMP; 669 decoded->op = M68K_CMP;
616 decoded->variant = VAR_IMMEDIATE; 670 decoded->variant = VAR_IMMEDIATE;
617 decoded->extra.size = (*istream >> 6) & 0x3; 671 decoded->extra.size = (opcode >> 6) & 0x3;
618 decoded->src.addr_mode = MODE_IMMEDIATE; 672 decoded->src.addr_mode = MODE_IMMEDIATE;
619 reg = *istream & 0x7; 673 reg = opcode & 0x7;
620 opmode = (*istream >> 3) & 0x7; 674 opmode = (opcode >> 3) & 0x7;
621 switch (decoded->extra.size) 675 switch (decoded->extra.size)
622 { 676 {
623 case OPSIZE_BYTE: 677 case OPSIZE_BYTE:
624 decoded->src.params.immed = *(++istream) & 0xFF; 678 decoded->src.params.immed = fetch(address, data) & 0xFF;
679 address += 2;
625 break; 680 break;
626 case OPSIZE_WORD: 681 case OPSIZE_WORD:
627 decoded->src.params.immed = *(++istream); 682 decoded->src.params.immed = fetch(address, data);
683 address += 2;
628 break; 684 break;
629 case OPSIZE_LONG: 685 case OPSIZE_LONG:
630 immed = *(++istream); 686 immed = fetch(address, data);
631 decoded->src.params.immed = (immed << 16) | *(++istream); 687 address += 2;
632 break; 688 decoded->src.params.immed = (immed << 16) | fetch(address, data);
633 } 689 address += 2;
634 istream = m68k_decode_op_ex(istream, opmode, reg, decoded->extra.size, &(decoded->dst)); 690 break;
635 if (!istream || !m68k_valid_immed_limited_dst(&(decoded->dst))) { 691 }
692 address = m68k_decode_op_ex(opcode, address, fetch, data, opmode, reg, decoded->extra.size, &(decoded->dst));
693 if (address == INVALID_ADDRESS || !m68k_valid_immed_limited_dst(&(decoded->dst))) {
636 decoded->op = M68K_INVALID; 694 decoded->op = M68K_INVALID;
637 break; 695 break;
638 } 696 }
639 break; 697 break;
640 case 7: 698 case 7:
641 #ifdef M68010 699 #ifdef M68010
642 decoded->op = M68K_MOVES; 700 decoded->op = M68K_MOVES;
643 decoded->extra.size = *istream >> 6 & 0x3; 701 decoded->extra.size = opcode >> 6 & 0x3;
644 immed = *(++istream); 702 immed = fetch(address, data);
703 address += 2;
645 reg = immed >> 12 & 0x7; 704 reg = immed >> 12 & 0x7;
646 opmode = immed & 0x8000 ? MODE_AREG : MODE_REG; 705 opmode = immed & 0x8000 ? MODE_AREG : MODE_REG;
647 if (immed & 0x800) { 706 if (immed & 0x800) {
648 decoded->src.addr_mode = opmode; 707 decoded->src.addr_mode = opmode;
649 decoded->src.params.regs.pri = reg; 708 decoded->src.params.regs.pri = reg;
650 m68k_decode_op_ex(istream, *start >> 3 & 0x7, *start & 0x7, decoded->extra.size, &(decoded->dst)); 709 address = m68k_decode_op_ex(opcode, address, fetch, data, *start >> 3 & 0x7, *start & 0x7, decoded->extra.size, &(decoded->dst));
651 } else { 710 } else {
652 m68k_decode_op_ex(istream, *start >> 3 & 0x7, *start & 0x7, decoded->extra.size, &(decoded->src)); 711 address = m68k_decode_op_ex(opcode, address, fetch, data, *start >> 3 & 0x7, *start & 0x7, decoded->extra.size, &(decoded->src));
653 decoded->dst.addr_mode = opmode; 712 decoded->dst.addr_mode = opmode;
654 decoded->dst.params.regs.pri = reg; 713 decoded->dst.params.regs.pri = reg;
655 } 714 }
656 #endif 715 #endif
657 break; 716 break;
661 case MOVE_BYTE: 720 case MOVE_BYTE:
662 case MOVE_LONG: 721 case MOVE_LONG:
663 case MOVE_WORD: 722 case MOVE_WORD:
664 decoded->op = M68K_MOVE; 723 decoded->op = M68K_MOVE;
665 decoded->extra.size = optype == MOVE_BYTE ? OPSIZE_BYTE : (optype == MOVE_WORD ? OPSIZE_WORD : OPSIZE_LONG); 724 decoded->extra.size = optype == MOVE_BYTE ? OPSIZE_BYTE : (optype == MOVE_WORD ? OPSIZE_WORD : OPSIZE_LONG);
666 opmode = (*istream >> 6) & 0x7; 725 opmode = (opcode >> 6) & 0x7;
667 reg = m68k_reg_quick_field(*istream); 726 reg = m68k_reg_quick_field(opcode);
668 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->src)); 727 address = m68k_decode_op(opcode, address, fetch, data, decoded->extra.size, &(decoded->src));
669 if (!istream || (decoded->src.addr_mode == MODE_AREG && optype == MOVE_BYTE)) { 728 if (address == INVALID_ADDRESS || (decoded->src.addr_mode == MODE_AREG && optype == MOVE_BYTE)) {
670 decoded->op = M68K_INVALID; 729 decoded->op = M68K_INVALID;
671 break; 730 break;
672 } 731 }
673 istream = m68k_decode_op_ex(istream, opmode, reg, decoded->extra.size, &(decoded->dst)); 732 address = m68k_decode_op_ex(opcode, address, fetch, data, opmode, reg, decoded->extra.size, &(decoded->dst));
674 if (!istream || decoded->dst.addr_mode > MODE_ABSOLUTE || (decoded->dst.addr_mode == MODE_AREG && optype == MOVE_BYTE)) { 733 if (address == INVALID_ADDRESS || decoded->dst.addr_mode > MODE_ABSOLUTE || (decoded->dst.addr_mode == MODE_AREG && optype == MOVE_BYTE)) {
675 decoded->op = M68K_INVALID; 734 decoded->op = M68K_INVALID;
676 break; 735 break;
677 } 736 }
678 break; 737 break;
679 case MISC: 738 case MISC:
680 739
681 if ((*istream & 0x1C0) == 0x1C0) { 740 if ((opcode & 0x1C0) == 0x1C0) {
682 decoded->op = M68K_LEA; 741 decoded->op = M68K_LEA;
683 decoded->extra.size = OPSIZE_LONG; 742 decoded->extra.size = OPSIZE_LONG;
684 decoded->dst.addr_mode = MODE_AREG; 743 decoded->dst.addr_mode = MODE_AREG;
685 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); 744 decoded->dst.params.regs.pri = m68k_reg_quick_field(opcode);
686 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->src)); 745 address = m68k_decode_op(opcode, address, fetch, data, decoded->extra.size, &(decoded->src));
687 if ( 746 if (
688 !istream || decoded->src.addr_mode == MODE_REG || decoded->src.addr_mode == MODE_AREG 747 address == INVALID_ADDRESS || decoded->src.addr_mode == MODE_REG || decoded->src.addr_mode == MODE_AREG
689 || decoded->src.addr_mode == MODE_AREG_POSTINC || decoded->src.addr_mode == MODE_AREG_PREDEC 748 || decoded->src.addr_mode == MODE_AREG_POSTINC || decoded->src.addr_mode == MODE_AREG_PREDEC
690 || decoded->src.addr_mode == MODE_IMMEDIATE 749 || decoded->src.addr_mode == MODE_IMMEDIATE
691 ) { 750 ) {
692 decoded->op = M68K_INVALID; 751 decoded->op = M68K_INVALID;
693 break; 752 break;
694 } 753 }
695 } else { 754 } else {
696 if (*istream & 0x100) { 755 if (opcode & 0x100) {
697 decoded->op = M68K_CHK; 756 decoded->op = M68K_CHK;
698 if ((*istream & 0x180) == 0x180) { 757 if ((opcode & 0x180) == 0x180) {
699 decoded->extra.size = OPSIZE_WORD; 758 decoded->extra.size = OPSIZE_WORD;
700 } else { 759 } else {
701 //only on M68020+ 760 //only on M68020+
702 #ifdef M68020 761 #ifdef M68020
703 decoded->extra.size = OPSIZE_LONG; 762 decoded->extra.size = OPSIZE_LONG;
705 decoded->op = M68K_INVALID; 764 decoded->op = M68K_INVALID;
706 break; 765 break;
707 #endif 766 #endif
708 } 767 }
709 decoded->dst.addr_mode = MODE_REG; 768 decoded->dst.addr_mode = MODE_REG;
710 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); 769 decoded->dst.params.regs.pri = m68k_reg_quick_field(opcode);
711 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->src)); 770 address = m68k_decode_op(opcode, address, fetch, data, decoded->extra.size, &(decoded->src));
712 if (!istream || decoded->src.addr_mode == MODE_AREG) { 771 if (address == INVALID_ADDRESS || decoded->src.addr_mode == MODE_AREG) {
713 decoded->op = M68K_INVALID; 772 decoded->op = M68K_INVALID;
714 break; 773 break;
715 } 774 }
716 } else { 775 } else {
717 opmode = (*istream >> 3) & 0x7; 776 opmode = (opcode >> 3) & 0x7;
718 if ((*istream & 0xB80) == 0x880 && opmode != MODE_REG && opmode != MODE_AREG) { 777 if ((opcode & 0xB80) == 0x880 && opmode != MODE_REG && opmode != MODE_AREG) {
719 //TODO: Check for invalid modes that are dependent on direction 778 //TODO: Check for invalid modes that are dependent on direction
720 decoded->op = M68K_MOVEM; 779 decoded->op = M68K_MOVEM;
721 decoded->extra.size = *istream & 0x40 ? OPSIZE_LONG : OPSIZE_WORD; 780 decoded->extra.size = opcode & 0x40 ? OPSIZE_LONG : OPSIZE_WORD;
722 reg = *istream & 0x7; 781 reg = opcode & 0x7;
723 if(*istream & 0x400) { 782 if(opcode & 0x400) {
724 decoded->dst.addr_mode = MODE_REG; 783 decoded->dst.addr_mode = MODE_REG;
725 decoded->dst.params.immed = *(++istream); 784 decoded->dst.params.immed = fetch(address, data);
726 istream = m68k_decode_op_ex(istream, opmode, reg, decoded->extra.size, &(decoded->src)); 785 address += 2;
727 if (!istream || decoded->src.addr_mode == MODE_AREG_PREDEC || decoded->src.addr_mode == MODE_IMMEDIATE) { 786 address = m68k_decode_op_ex(opcode, address, fetch, data, opmode, reg, decoded->extra.size, &(decoded->src));
787 if (address == INVALID_ADDRESS || decoded->src.addr_mode == MODE_AREG_PREDEC || decoded->src.addr_mode == MODE_IMMEDIATE) {
728 decoded->op = M68K_INVALID; 788 decoded->op = M68K_INVALID;
729 break; 789 break;
730 } 790 }
731 if (decoded->src.addr_mode == MODE_PC_DISPLACE || decoded->src.addr_mode == MODE_PC_INDEX_DISP8) { 791 if (decoded->src.addr_mode == MODE_PC_DISPLACE || decoded->src.addr_mode == MODE_PC_INDEX_DISP8) {
732 //adjust displacement to account for extra instruction word 792 //adjust displacement to account for extra instruction word
733 decoded->src.params.regs.displacement += 2; 793 decoded->src.params.regs.displacement += 2;
734 } 794 }
735 } else { 795 } else {
736 decoded->src.addr_mode = MODE_REG; 796 decoded->src.addr_mode = MODE_REG;
737 decoded->src.params.immed = *(++istream); 797 decoded->src.params.immed = fetch(address, data);
738 istream = m68k_decode_op_ex(istream, opmode, reg, decoded->extra.size, &(decoded->dst)); 798 address += 2;
739 if (!istream || !m68k_valid_movem_dst(&decoded->dst)) { 799 address = m68k_decode_op_ex(opcode, address, fetch, data, opmode, reg, decoded->extra.size, &(decoded->dst));
800 if (address == INVALID_ADDRESS || !m68k_valid_movem_dst(&decoded->dst)) {
740 decoded->op = M68K_INVALID; 801 decoded->op = M68K_INVALID;
741 break; 802 break;
742 } 803 }
743 } 804 }
744 } else { 805 } else {
745 optype = (*istream >> 9) & 0x7; 806 optype = (opcode >> 9) & 0x7;
746 size = (*istream >> 6) & 0x3; 807 size = (opcode >> 6) & 0x3;
747 switch(optype) 808 switch(optype)
748 { 809 {
749 case 0: 810 case 0:
750 //Move from SR or NEGX 811 //Move from SR or NEGX
751 if (size == OPSIZE_INVALID) { 812 if (size == OPSIZE_INVALID) {
753 size = OPSIZE_WORD; 814 size = OPSIZE_WORD;
754 } else { 815 } else {
755 decoded->op = M68K_NEGX; 816 decoded->op = M68K_NEGX;
756 } 817 }
757 decoded->extra.size = size; 818 decoded->extra.size = size;
758 istream= m68k_decode_op(istream, size, &(decoded->dst)); 819 address = m68k_decode_op(opcode, address, fetch, data, size, &(decoded->dst));
759 if (!istream || !m68k_valid_immed_limited_dst(&decoded->dst)) { 820 if (address == INVALID_ADDRESS || !m68k_valid_immed_limited_dst(&decoded->dst)) {
760 decoded->op = M68K_INVALID; 821 decoded->op = M68K_INVALID;
761 break; 822 break;
762 } 823 }
763 break; 824 break;
764 case 1: 825 case 1:
772 #endif 833 #endif
773 } else { 834 } else {
774 decoded->op = M68K_CLR; 835 decoded->op = M68K_CLR;
775 } 836 }
776 decoded->extra.size = size; 837 decoded->extra.size = size;
777 istream= m68k_decode_op(istream, size, &(decoded->dst)); 838 address = m68k_decode_op(opcode, address, fetch, data, size, &(decoded->dst));
778 if (!istream || !m68k_valid_immed_limited_dst(&decoded->dst)) { 839 if (address == INVALID_ADDRESS || !m68k_valid_immed_limited_dst(&decoded->dst)) {
779 decoded->op = M68K_INVALID; 840 decoded->op = M68K_INVALID;
780 break; 841 break;
781 } 842 }
782 break; 843 break;
783 case 2: 844 case 2:
784 //MOVE to CCR or NEG 845 //MOVE to CCR or NEG
785 if (size == OPSIZE_INVALID) { 846 if (size == OPSIZE_INVALID) {
786 decoded->op = M68K_MOVE_CCR; 847 decoded->op = M68K_MOVE_CCR;
787 size = OPSIZE_WORD; 848 size = OPSIZE_WORD;
788 istream= m68k_decode_op(istream, size, &(decoded->src)); 849 address = m68k_decode_op(opcode, address, fetch, data, size, &(decoded->src));
789 if (!istream || decoded->src.addr_mode == MODE_AREG) { 850 if (address == INVALID_ADDRESS || decoded->src.addr_mode == MODE_AREG) {
790 decoded->op = M68K_INVALID; 851 decoded->op = M68K_INVALID;
791 break; 852 break;
792 } 853 }
793 } else { 854 } else {
794 decoded->op = M68K_NEG; 855 decoded->op = M68K_NEG;
795 istream= m68k_decode_op(istream, size, &(decoded->dst)); 856 address = m68k_decode_op(opcode, address, fetch, data, size, &(decoded->dst));
796 if (!istream || !m68k_valid_immed_limited_dst(&decoded->dst)) { 857 if (address == INVALID_ADDRESS || !m68k_valid_immed_limited_dst(&decoded->dst)) {
797 decoded->op = M68K_INVALID; 858 decoded->op = M68K_INVALID;
798 break; 859 break;
799 } 860 }
800 } 861 }
801 decoded->extra.size = size; 862 decoded->extra.size = size;
803 case 3: 864 case 3:
804 //MOVE to SR or NOT 865 //MOVE to SR or NOT
805 if (size == OPSIZE_INVALID) { 866 if (size == OPSIZE_INVALID) {
806 decoded->op = M68K_MOVE_SR; 867 decoded->op = M68K_MOVE_SR;
807 size = OPSIZE_WORD; 868 size = OPSIZE_WORD;
808 istream= m68k_decode_op(istream, size, &(decoded->src)); 869 address = m68k_decode_op(opcode, address, fetch, data, size, &(decoded->src));
809 if (!istream || decoded->src.addr_mode == MODE_AREG) { 870 if (address == INVALID_ADDRESS || decoded->src.addr_mode == MODE_AREG) {
810 decoded->op = M68K_INVALID; 871 decoded->op = M68K_INVALID;
811 break; 872 break;
812 } 873 }
813 } else { 874 } else {
814 decoded->op = M68K_NOT; 875 decoded->op = M68K_NOT;
815 istream= m68k_decode_op(istream, size, &(decoded->dst)); 876 address = m68k_decode_op(opcode, address, fetch, data, size, &(decoded->dst));
816 if (!istream || !m68k_valid_immed_limited_dst(&decoded->dst)) { 877 if (address == INVALID_ADDRESS || !m68k_valid_immed_limited_dst(&decoded->dst)) {
817 decoded->op = M68K_INVALID; 878 decoded->op = M68K_INVALID;
818 break; 879 break;
819 } 880 }
820 } 881 }
821 decoded->extra.size = size; 882 decoded->extra.size = size;
822 break; 883 break;
823 case 4: 884 case 4:
824 //EXT, EXTB, LINK.l, NBCD, SWAP, BKPT, PEA 885 //EXT, EXTB, LINK.l, NBCD, SWAP, BKPT, PEA
825 switch((*istream >> 3) & 0x3F) 886 switch((opcode >> 3) & 0x3F)
826 { 887 {
827 case 1: 888 case 1:
828 #ifdef M68020 889 #ifdef M68020
829 decoded->op = M68K_LINK; 890 decoded->op = M68K_LINK;
830 decoded->extra.size = OPSIZE_LONG; 891 decoded->extra.size = OPSIZE_LONG;
831 reg = *istream & 0x7; 892 reg = opcode & 0x7;
832 immed = *(++istream) << 16; 893 immed = fetch(address, data) << 16;
833 immed |= *(++istream); 894 address += 2;
895 immed |= fetch(address, data);
896 address += 2;
834 #endif 897 #endif
835 break; 898 break;
836 case 8: 899 case 8:
837 decoded->op = M68K_SWAP; 900 decoded->op = M68K_SWAP;
838 decoded->src.addr_mode = MODE_REG; 901 decoded->src.addr_mode = MODE_REG;
839 decoded->src.params.regs.pri = *istream & 0x7; 902 decoded->src.params.regs.pri = opcode & 0x7;
840 decoded->extra.size = OPSIZE_WORD; 903 decoded->extra.size = OPSIZE_WORD;
841 break; 904 break;
842 case 9: 905 case 9:
843 #ifdef M68010 906 #ifdef M68010
844 decoded->op = M68K_BKPT; 907 decoded->op = M68K_BKPT;
845 decoded->src.addr_mode = MODE_IMMEDIATE; 908 decoded->src.addr_mode = MODE_IMMEDIATE;
846 decoded->extra.size = OPSIZE_UNSIZED; 909 decoded->extra.size = OPSIZE_UNSIZED;
847 decoded->src.params.immed = *istream & 0x7; 910 decoded->src.params.immed = opcode & 0x7;
848 #endif 911 #endif
849 break; 912 break;
850 case 0x10: 913 case 0x10:
851 decoded->op = M68K_EXT; 914 decoded->op = M68K_EXT;
852 decoded->dst.addr_mode = MODE_REG; 915 decoded->dst.addr_mode = MODE_REG;
853 decoded->dst.params.regs.pri = *istream & 0x7; 916 decoded->dst.params.regs.pri = opcode & 0x7;
854 decoded->extra.size = OPSIZE_WORD; 917 decoded->extra.size = OPSIZE_WORD;
855 break; 918 break;
856 case 0x18: 919 case 0x18:
857 decoded->op = M68K_EXT; 920 decoded->op = M68K_EXT;
858 decoded->dst.addr_mode = MODE_REG; 921 decoded->dst.addr_mode = MODE_REG;
859 decoded->dst.params.regs.pri = *istream & 0x7; 922 decoded->dst.params.regs.pri = opcode & 0x7;
860 decoded->extra.size = OPSIZE_LONG; 923 decoded->extra.size = OPSIZE_LONG;
861 break; 924 break;
862 case 0x38: 925 case 0x38:
863 #ifdef M68020 926 #ifdef M68020
864 #endif 927 #endif
865 break; 928 break;
866 default: 929 default:
867 if (!(*istream & 0x1C0)) { 930 if (!(opcode & 0x1C0)) {
868 decoded->op = M68K_NBCD; 931 decoded->op = M68K_NBCD;
869 decoded->extra.size = OPSIZE_BYTE; 932 decoded->extra.size = OPSIZE_BYTE;
870 istream = m68k_decode_op(istream, OPSIZE_BYTE, &(decoded->dst)); 933 address = m68k_decode_op(opcode, address, fetch, data, OPSIZE_BYTE, &(decoded->dst));
871 if (!istream || !m68k_valid_immed_limited_dst(&decoded->dst)) { 934 if (address == INVALID_ADDRESS || !m68k_valid_immed_limited_dst(&decoded->dst)) {
872 decoded->op = M68K_INVALID; 935 decoded->op = M68K_INVALID;
873 break; 936 break;
874 } 937 }
875 } else if((*istream & 0x1C0) == 0x40) { 938 } else if((opcode & 0x1C0) == 0x40) {
876 decoded->op = M68K_PEA; 939 decoded->op = M68K_PEA;
877 decoded->extra.size = OPSIZE_LONG; 940 decoded->extra.size = OPSIZE_LONG;
878 istream = m68k_decode_op(istream, OPSIZE_LONG, &(decoded->src)); 941 address = m68k_decode_op(opcode, address, fetch, data, OPSIZE_LONG, &(decoded->src));
879 if ( 942 if (
880 !istream || decoded->src.addr_mode == MODE_REG || decoded->src.addr_mode == MODE_AREG 943 address == INVALID_ADDRESS || decoded->src.addr_mode == MODE_REG || decoded->src.addr_mode == MODE_AREG
881 || decoded->src.addr_mode == MODE_AREG_POSTINC || decoded->src.addr_mode == MODE_AREG_PREDEC 944 || decoded->src.addr_mode == MODE_AREG_POSTINC || decoded->src.addr_mode == MODE_AREG_PREDEC
882 || decoded->src.addr_mode == MODE_IMMEDIATE 945 || decoded->src.addr_mode == MODE_IMMEDIATE
883 ) { 946 ) {
884 decoded->op = M68K_INVALID; 947 decoded->op = M68K_INVALID;
885 break; 948 break;
887 } 950 }
888 } 951 }
889 break; 952 break;
890 case 5: 953 case 5:
891 //BGND, ILLEGAL, TAS, TST 954 //BGND, ILLEGAL, TAS, TST
892 optype = *istream & 0xFF; 955 optype = opcode & 0xFF;
893 if (optype == 0xFA) { 956 if (optype == 0xFA) {
894 //BGND - CPU32 only 957 //BGND - CPU32 only
895 } else if (optype == 0xFC) { 958 } else if (optype == 0xFC) {
896 decoded->op = M68K_ILLEGAL; 959 decoded->op = M68K_ILLEGAL;
897 decoded->extra.size = OPSIZE_UNSIZED; 960 decoded->extra.size = OPSIZE_UNSIZED;
898 } else { 961 } else {
899 if (size == OPSIZE_INVALID) { 962 if (size == OPSIZE_INVALID) {
900 decoded->op = M68K_TAS; 963 decoded->op = M68K_TAS;
901 decoded->extra.size = OPSIZE_BYTE; 964 decoded->extra.size = OPSIZE_BYTE;
902 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->dst)); 965 address = m68k_decode_op(opcode, address, fetch, data, decoded->extra.size, &(decoded->dst));
903 if (!istream || !m68k_valid_immed_limited_dst(&decoded->dst)) { 966 if (address == INVALID_ADDRESS || !m68k_valid_immed_limited_dst(&decoded->dst)) {
904 decoded->op = M68K_INVALID; 967 decoded->op = M68K_INVALID;
905 break; 968 break;
906 } 969 }
907 } else { 970 } else {
908 decoded->op = M68K_TST; 971 decoded->op = M68K_TST;
909 decoded->extra.size = size; 972 decoded->extra.size = size;
910 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->src)); 973 address = m68k_decode_op(opcode, address, fetch, data, decoded->extra.size, &(decoded->src));
911 if (!istream) { 974 if (address == INVALID_ADDRESS) {
912 decoded->op = M68K_INVALID; 975 decoded->op = M68K_INVALID;
913 break; 976 break;
914 } 977 }
915 #ifndef M68020 978 #ifndef M68020
916 if (!m68k_valid_immed_limited_dst(&decoded->src)) { 979 if (!m68k_valid_immed_limited_dst(&decoded->src)) {
927 //TODO: Implement these for 68020+ support 990 //TODO: Implement these for 68020+ support
928 #endif 991 #endif
929 break; 992 break;
930 case 7: 993 case 7:
931 //TRAP, LINK.w, UNLNK, MOVE USP, RESET, NOP, STOP, RTE, RTD, RTS, TRAPV, RTR, MOVEC, JSR, JMP 994 //TRAP, LINK.w, UNLNK, MOVE USP, RESET, NOP, STOP, RTE, RTD, RTS, TRAPV, RTR, MOVEC, JSR, JMP
932 if (*istream & 0x80) { 995 if (opcode & 0x80) {
933 //JSR, JMP 996 //JSR, JMP
934 if (*istream & 0x40) { 997 if (opcode & 0x40) {
935 decoded->op = M68K_JMP; 998 decoded->op = M68K_JMP;
936 } else { 999 } else {
937 decoded->op = M68K_JSR; 1000 decoded->op = M68K_JSR;
938 } 1001 }
939 decoded->extra.size = OPSIZE_UNSIZED; 1002 decoded->extra.size = OPSIZE_UNSIZED;
940 istream = m68k_decode_op(istream, OPSIZE_UNSIZED, &(decoded->src)); 1003 address = m68k_decode_op(opcode, address, fetch, data, OPSIZE_UNSIZED, &(decoded->src));
941 if ( 1004 if (
942 !istream 1005 address == INVALID_ADDRESS
943 || (decoded->src.addr_mode < MODE_AREG_DISPLACE && decoded->src.addr_mode != MODE_AREG_INDIRECT) 1006 || (decoded->src.addr_mode < MODE_AREG_DISPLACE && decoded->src.addr_mode != MODE_AREG_INDIRECT)
944 || decoded->src.addr_mode == MODE_IMMEDIATE 1007 || decoded->src.addr_mode == MODE_IMMEDIATE
945 ) { 1008 ) {
946 decoded->op = M68K_INVALID; 1009 decoded->op = M68K_INVALID;
947 break; 1010 break;
948 } 1011 }
949 } else { 1012 } else {
950 //it would appear bit 6 needs to be set for it to be a valid instruction here 1013 //it would appear bit 6 needs to be set for it to be a valid instruction here
951 if (!(*istream & 0x40)) { 1014 if (!(opcode & 0x40)) {
952 decoded->op = M68K_INVALID; 1015 decoded->op = M68K_INVALID;
953 break; 1016 break;
954 } 1017 }
955 switch((*istream >> 3) & 0x7) 1018 switch((opcode >> 3) & 0x7)
956 { 1019 {
957 case 0: 1020 case 0:
958 case 1: 1021 case 1:
959 //TRAP 1022 //TRAP
960 decoded->op = M68K_TRAP; 1023 decoded->op = M68K_TRAP;
961 decoded->extra.size = OPSIZE_UNSIZED; 1024 decoded->extra.size = OPSIZE_UNSIZED;
962 decoded->src.addr_mode = MODE_IMMEDIATE; 1025 decoded->src.addr_mode = MODE_IMMEDIATE;
963 decoded->src.params.immed = *istream & 0xF; 1026 decoded->src.params.immed = opcode & 0xF;
964 break; 1027 break;
965 case 2: 1028 case 2:
966 //LINK.w 1029 //LINK.w
967 decoded->op = M68K_LINK; 1030 decoded->op = M68K_LINK;
968 decoded->extra.size = OPSIZE_WORD; 1031 decoded->extra.size = OPSIZE_WORD;
969 decoded->src.addr_mode = MODE_AREG; 1032 decoded->src.addr_mode = MODE_AREG;
970 decoded->src.params.regs.pri = *istream & 0x7; 1033 decoded->src.params.regs.pri = opcode & 0x7;
971 decoded->dst.addr_mode = MODE_IMMEDIATE; 1034 decoded->dst.addr_mode = MODE_IMMEDIATE;
972 decoded->dst.params.immed = sign_extend16(*(++istream)); 1035 decoded->dst.params.immed = sign_extend16(fetch(address, data));
1036 address += 2;
973 break; 1037 break;
974 case 3: 1038 case 3:
975 //UNLK 1039 //UNLK
976 decoded->op = M68K_UNLK; 1040 decoded->op = M68K_UNLK;
977 decoded->extra.size = OPSIZE_UNSIZED; 1041 decoded->extra.size = OPSIZE_UNSIZED;
978 decoded->dst.addr_mode = MODE_AREG; 1042 decoded->dst.addr_mode = MODE_AREG;
979 decoded->dst.params.regs.pri = *istream & 0x7; 1043 decoded->dst.params.regs.pri = opcode & 0x7;
980 break; 1044 break;
981 case 4: 1045 case 4:
982 case 5: 1046 case 5:
983 //MOVE USP 1047 //MOVE USP
984 decoded->op = M68K_MOVE_USP; 1048 decoded->op = M68K_MOVE_USP;
985 if (*istream & 0x8) { 1049 if (opcode & 0x8) {
986 decoded->dst.addr_mode = MODE_AREG; 1050 decoded->dst.addr_mode = MODE_AREG;
987 decoded->dst.params.regs.pri = *istream & 0x7; 1051 decoded->dst.params.regs.pri = opcode & 0x7;
988 } else { 1052 } else {
989 decoded->src.addr_mode = MODE_AREG; 1053 decoded->src.addr_mode = MODE_AREG;
990 decoded->src.params.regs.pri = *istream & 0x7; 1054 decoded->src.params.regs.pri = opcode & 0x7;
991 } 1055 }
992 break; 1056 break;
993 case 6: 1057 case 6:
994 decoded->extra.size = OPSIZE_UNSIZED; 1058 decoded->extra.size = OPSIZE_UNSIZED;
995 switch(*istream & 0x7) 1059 switch(opcode & 0x7)
996 { 1060 {
997 case 0: 1061 case 0:
998 decoded->op = M68K_RESET; 1062 decoded->op = M68K_RESET;
999 break; 1063 break;
1000 case 1: 1064 case 1:
1001 decoded->op = M68K_NOP; 1065 decoded->op = M68K_NOP;
1002 break; 1066 break;
1003 case 2: 1067 case 2:
1004 decoded->op = M68K_STOP; 1068 decoded->op = M68K_STOP;
1005 decoded->src.addr_mode = MODE_IMMEDIATE; 1069 decoded->src.addr_mode = MODE_IMMEDIATE;
1006 decoded->src.params.immed =*(++istream); 1070 decoded->src.params.immed =fetch(address, data);
1071 address += 2;
1007 break; 1072 break;
1008 case 3: 1073 case 3:
1009 decoded->op = M68K_RTE; 1074 decoded->op = M68K_RTE;
1010 break; 1075 break;
1011 case 4: 1076 case 4:
1012 #ifdef M68010 1077 #ifdef M68010
1013 decoded->op = M68K_RTD; 1078 decoded->op = M68K_RTD;
1014 decoded->src.addr_mode = MODE_IMMEDIATE; 1079 decoded->src.addr_mode = MODE_IMMEDIATE;
1015 decoded->src.params.immed =*(++istream); 1080 decoded->src.params.immed =fetch(address, data);
1081 address += 2;
1016 #endif 1082 #endif
1017 break; 1083 break;
1018 case 5: 1084 case 5:
1019 decoded->op = M68K_RTS; 1085 decoded->op = M68K_RTS;
1020 break; 1086 break;
1028 break; 1094 break;
1029 case 7: 1095 case 7:
1030 //MOVEC 1096 //MOVEC
1031 #ifdef M68010 1097 #ifdef M68010
1032 decoded->op = M68K_MOVEC; 1098 decoded->op = M68K_MOVEC;
1033 immed = *(++istream); 1099 immed = fetch(address, data);
1100 address += 2;
1034 reg = immed >> 12 & 0x7; 1101 reg = immed >> 12 & 0x7;
1035 opmode = immed & 0x8000 ? MODE_AREG : MODE_REG; 1102 opmode = immed & 0x8000 ? MODE_AREG : MODE_REG;
1036 immed &= 0xFFF; 1103 immed &= 0xFFF;
1037 if (immed & 0x800) { 1104 if (immed & 0x800) {
1038 if (immed > MAX_HIGH_CR) { 1105 if (immed > MAX_HIGH_CR) {
1065 } 1132 }
1066 } 1133 }
1067 } 1134 }
1068 break; 1135 break;
1069 case QUICK_ARITH_LOOP: 1136 case QUICK_ARITH_LOOP:
1070 size = (*istream >> 6) & 3; 1137 size = (opcode >> 6) & 3;
1071 if (size == 0x3) { 1138 if (size == 0x3) {
1072 //DBcc, TRAPcc or Scc 1139 //DBcc, TRAPcc or Scc
1073 m68k_decode_cond(*istream, decoded); 1140 m68k_decode_cond(opcode, decoded);
1074 if (((*istream >> 3) & 0x7) == 1) { 1141 if (((opcode >> 3) & 0x7) == 1) {
1075 decoded->op = M68K_DBCC; 1142 decoded->op = M68K_DBCC;
1076 decoded->src.addr_mode = MODE_IMMEDIATE; 1143 decoded->src.addr_mode = MODE_IMMEDIATE;
1077 decoded->dst.addr_mode = MODE_REG; 1144 decoded->dst.addr_mode = MODE_REG;
1078 decoded->dst.params.regs.pri = *istream & 0x7; 1145 decoded->dst.params.regs.pri = opcode & 0x7;
1079 decoded->src.params.immed = sign_extend16(*(++istream)); 1146 decoded->src.params.immed = sign_extend16(fetch(address, data));
1080 } else if(((*istream >> 3) & 0x7) == 1 && (*istream & 0x7) > 1 && (*istream & 0x7) < 5) { 1147 address += 2;
1148 } else if(((opcode >> 3) & 0x7) == 1 && (opcode & 0x7) > 1 && (opcode & 0x7) < 5) {
1081 #ifdef M68020 1149 #ifdef M68020
1082 decoded->op = M68K_TRAPCC; 1150 decoded->op = M68K_TRAPCC;
1083 decoded->src.addr_mode = MODE_IMMEDIATE; 1151 decoded->src.addr_mode = MODE_IMMEDIATE;
1084 //TODO: Figure out what to do with OPMODE and optional extention words 1152 //TODO: Figure out what to do with OPMODE and optional extention words
1085 #endif 1153 #endif
1086 } else { 1154 } else {
1087 decoded->op = M68K_SCC; 1155 decoded->op = M68K_SCC;
1088 decoded->extra.cond = (*istream >> 8) & 0xF; 1156 decoded->extra.cond = (opcode >> 8) & 0xF;
1089 istream = m68k_decode_op(istream, OPSIZE_BYTE, &(decoded->dst)); 1157 address = m68k_decode_op(opcode, address, fetch, data, OPSIZE_BYTE, &(decoded->dst));
1090 if (!istream || !m68k_valid_immed_limited_dst(&decoded->dst)) { 1158 if (address == INVALID_ADDRESS || !m68k_valid_immed_limited_dst(&decoded->dst)) {
1091 decoded->op = M68K_INVALID; 1159 decoded->op = M68K_INVALID;
1092 break; 1160 break;
1093 } 1161 }
1094 } 1162 }
1095 } else { 1163 } else {
1096 //ADDQ, SUBQ 1164 //ADDQ, SUBQ
1097 decoded->variant = VAR_QUICK; 1165 decoded->variant = VAR_QUICK;
1098 decoded->extra.size = size; 1166 decoded->extra.size = size;
1099 decoded->src.addr_mode = MODE_IMMEDIATE; 1167 decoded->src.addr_mode = MODE_IMMEDIATE;
1100 immed = m68k_reg_quick_field(*istream); 1168 immed = m68k_reg_quick_field(opcode);
1101 if (!immed) { 1169 if (!immed) {
1102 immed = 8; 1170 immed = 8;
1103 } 1171 }
1104 decoded->src.params.immed = immed; 1172 decoded->src.params.immed = immed;
1105 if (*istream & 0x100) { 1173 if (opcode & 0x100) {
1106 decoded->op = M68K_SUB; 1174 decoded->op = M68K_SUB;
1107 } else { 1175 } else {
1108 decoded->op = M68K_ADD; 1176 decoded->op = M68K_ADD;
1109 } 1177 }
1110 istream = m68k_decode_op(istream, size, &(decoded->dst)); 1178 address = m68k_decode_op(opcode, address, fetch, data, size, &(decoded->dst));
1111 if (!istream || decoded->dst.addr_mode > MODE_ABSOLUTE || (size == OPSIZE_BYTE && decoded->dst.addr_mode == MODE_AREG)) { 1179 if (address == INVALID_ADDRESS || decoded->dst.addr_mode > MODE_ABSOLUTE || (size == OPSIZE_BYTE && decoded->dst.addr_mode == MODE_AREG)) {
1112 decoded->op = M68K_INVALID; 1180 decoded->op = M68K_INVALID;
1113 break; 1181 break;
1114 } 1182 }
1115 } 1183 }
1116 break; 1184 break;
1117 case BRANCH: 1185 case BRANCH:
1118 m68k_decode_cond(*istream, decoded); 1186 m68k_decode_cond(opcode, decoded);
1119 decoded->op = decoded->extra.cond == COND_FALSE ? M68K_BSR : M68K_BCC; 1187 decoded->op = decoded->extra.cond == COND_FALSE ? M68K_BSR : M68K_BCC;
1120 decoded->src.addr_mode = MODE_IMMEDIATE; 1188 decoded->src.addr_mode = MODE_IMMEDIATE;
1121 immed = *istream & 0xFF; 1189 immed = opcode & 0xFF;
1122 if (immed == 0) { 1190 if (immed == 0) {
1123 decoded->variant = VAR_WORD; 1191 decoded->variant = VAR_WORD;
1124 immed = *(++istream); 1192 immed = fetch(address, data);
1193 address += 2;
1125 immed = sign_extend16(immed); 1194 immed = sign_extend16(immed);
1126 #ifdef M68020 1195 #ifdef M68020
1127 } else if (immed == 0xFF) { 1196 } else if (immed == 0xFF) {
1128 decoded->variant = VAR_LONG; 1197 decoded->variant = VAR_LONG;
1129 immed = *(++istream) << 16; 1198 immed = fetch(address, data) << 16;
1130 immed |= *(++istream); 1199 address += 2;
1200 immed |= fetch(address, data);
1201 address += 2;
1131 #endif 1202 #endif
1132 } else { 1203 } else {
1133 decoded->variant = VAR_BYTE; 1204 decoded->variant = VAR_BYTE;
1134 immed = sign_extend8(immed); 1205 immed = sign_extend8(immed);
1135 } 1206 }
1136 decoded->src.params.immed = immed; 1207 decoded->src.params.immed = immed;
1137 break; 1208 break;
1138 case MOVEQ: 1209 case MOVEQ:
1139 if (*istream & 0x100) { 1210 if (opcode & 0x100) {
1140 decoded->op = M68K_INVALID; 1211 decoded->op = M68K_INVALID;
1141 break; 1212 break;
1142 } 1213 }
1143 decoded->op = M68K_MOVE; 1214 decoded->op = M68K_MOVE;
1144 decoded->variant = VAR_QUICK; 1215 decoded->variant = VAR_QUICK;
1145 decoded->extra.size = OPSIZE_LONG; 1216 decoded->extra.size = OPSIZE_LONG;
1146 decoded->src.addr_mode = MODE_IMMEDIATE; 1217 decoded->src.addr_mode = MODE_IMMEDIATE;
1147 decoded->src.params.immed = sign_extend8(*istream & 0xFF); 1218 decoded->src.params.immed = sign_extend8(opcode & 0xFF);
1148 decoded->dst.addr_mode = MODE_REG; 1219 decoded->dst.addr_mode = MODE_REG;
1149 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); 1220 decoded->dst.params.regs.pri = m68k_reg_quick_field(opcode);
1150 immed = *istream & 0xFF; 1221 immed = opcode & 0xFF;
1151 break; 1222 break;
1152 case OR_DIV_SBCD: 1223 case OR_DIV_SBCD:
1153 //for OR, if opmode bit 2 is 1, then src = Dn, dst = <ea> 1224 //for OR, if opmode bit 2 is 1, then src = Dn, dst = <ea>
1154 opmode = (*istream >> 6) & 0x7; 1225 opmode = (opcode >> 6) & 0x7;
1155 size = opmode & 0x3; 1226 size = opmode & 0x3;
1156 if (size == OPSIZE_INVALID || (opmode & 0x4 && !(*istream & 0x30))) { 1227 if (size == OPSIZE_INVALID || (opmode & 0x4 && !(opcode & 0x30))) {
1157 switch(opmode) 1228 switch(opmode)
1158 { 1229 {
1159 case 3: 1230 case 3:
1160 decoded->op = M68K_DIVU; 1231 decoded->op = M68K_DIVU;
1161 decoded->extra.size = OPSIZE_WORD; 1232 decoded->extra.size = OPSIZE_WORD;
1162 decoded->dst.addr_mode = MODE_REG; 1233 decoded->dst.addr_mode = MODE_REG;
1163 decoded->dst.params.regs.pri = (*istream >> 9) & 0x7; 1234 decoded->dst.params.regs.pri = (opcode >> 9) & 0x7;
1164 istream = m68k_decode_op(istream, OPSIZE_WORD, &(decoded->src)); 1235 address = m68k_decode_op(opcode, address, fetch, data, OPSIZE_WORD, &(decoded->src));
1165 if (!istream || decoded->src.addr_mode == MODE_AREG) { 1236 if (address == INVALID_ADDRESS || decoded->src.addr_mode == MODE_AREG) {
1166 decoded->op = M68K_INVALID; 1237 decoded->op = M68K_INVALID;
1167 break; 1238 break;
1168 } 1239 }
1169 break; 1240 break;
1170 case 4: 1241 case 4:
1171 decoded->op = M68K_SBCD; 1242 decoded->op = M68K_SBCD;
1172 decoded->extra.size = OPSIZE_BYTE; 1243 decoded->extra.size = OPSIZE_BYTE;
1173 decoded->dst.addr_mode = decoded->src.addr_mode = *istream & 0x8 ? MODE_AREG_PREDEC : MODE_REG; 1244 decoded->dst.addr_mode = decoded->src.addr_mode = opcode & 0x8 ? MODE_AREG_PREDEC : MODE_REG;
1174 decoded->src.params.regs.pri = *istream & 0x7; 1245 decoded->src.params.regs.pri = opcode & 0x7;
1175 decoded->dst.params.regs.pri = (*istream >> 9) & 0x7; 1246 decoded->dst.params.regs.pri = (opcode >> 9) & 0x7;
1176 break; 1247 break;
1177 case 5: 1248 case 5:
1178 #ifdef M68020 1249 #ifdef M68020
1179 #endif 1250 #endif
1180 break; 1251 break;
1184 break; 1255 break;
1185 case 7: 1256 case 7:
1186 decoded->op = M68K_DIVS; 1257 decoded->op = M68K_DIVS;
1187 decoded->extra.size = OPSIZE_WORD; 1258 decoded->extra.size = OPSIZE_WORD;
1188 decoded->dst.addr_mode = MODE_REG; 1259 decoded->dst.addr_mode = MODE_REG;
1189 decoded->dst.params.regs.pri = (*istream >> 9) & 0x7; 1260 decoded->dst.params.regs.pri = (opcode >> 9) & 0x7;
1190 istream = m68k_decode_op(istream, OPSIZE_WORD, &(decoded->src)); 1261 address = m68k_decode_op(opcode, address, fetch, data, OPSIZE_WORD, &(decoded->src));
1191 if (!istream || decoded->src.addr_mode == MODE_AREG) { 1262 if (address == INVALID_ADDRESS || decoded->src.addr_mode == MODE_AREG) {
1192 decoded->op = M68K_INVALID; 1263 decoded->op = M68K_INVALID;
1193 break; 1264 break;
1194 } 1265 }
1195 break; 1266 break;
1196 } 1267 }
1197 } else { 1268 } else {
1198 decoded->op = M68K_OR; 1269 decoded->op = M68K_OR;
1199 decoded->extra.size = size; 1270 decoded->extra.size = size;
1200 if (opmode & 0x4) { 1271 if (opmode & 0x4) {
1201 decoded->src.addr_mode = MODE_REG; 1272 decoded->src.addr_mode = MODE_REG;
1202 decoded->src.params.regs.pri = (*istream >> 9) & 0x7; 1273 decoded->src.params.regs.pri = (opcode >> 9) & 0x7;
1203 istream = m68k_decode_op(istream, size, &(decoded->dst)); 1274 address = m68k_decode_op(opcode, address, fetch, data, size, &(decoded->dst));
1204 if (!istream || !m68k_valid_full_arith_dst(&(decoded->dst))) { 1275 if (address == INVALID_ADDRESS || !m68k_valid_full_arith_dst(&(decoded->dst))) {
1205 decoded->op = M68K_INVALID; 1276 decoded->op = M68K_INVALID;
1206 break; 1277 break;
1207 } 1278 }
1208 } else { 1279 } else {
1209 decoded->dst.addr_mode = MODE_REG; 1280 decoded->dst.addr_mode = MODE_REG;
1210 decoded->dst.params.regs.pri = (*istream >> 9) & 0x7; 1281 decoded->dst.params.regs.pri = (opcode >> 9) & 0x7;
1211 istream = m68k_decode_op(istream, size, &(decoded->src)); 1282 address = m68k_decode_op(opcode, address, fetch, data, size, &(decoded->src));
1212 if (!istream || decoded->src.addr_mode == MODE_AREG) { 1283 if (address == INVALID_ADDRESS || decoded->src.addr_mode == MODE_AREG) {
1213 decoded->op = M68K_INVALID; 1284 decoded->op = M68K_INVALID;
1214 break; 1285 break;
1215 } 1286 }
1216 } 1287 }
1217 } 1288 }
1218 break; 1289 break;
1219 case SUB_SUBX: 1290 case SUB_SUBX:
1220 size = (*istream >> 6) & 0x3; 1291 size = (opcode >> 6) & 0x3;
1221 decoded->op = M68K_SUB; 1292 decoded->op = M68K_SUB;
1222 if (*istream & 0x100) { 1293 if (opcode & 0x100) {
1223 //<ea> destination, SUBA.l or SUBX 1294 //<ea> destination, SUBA.l or SUBX
1224 if (*istream & 0x30 || size == OPSIZE_INVALID) { 1295 if (opcode & 0x30 || size == OPSIZE_INVALID) {
1225 if (size == OPSIZE_INVALID) { 1296 if (size == OPSIZE_INVALID) {
1226 //SUBA.l 1297 //SUBA.l
1227 decoded->extra.size = OPSIZE_LONG; 1298 decoded->extra.size = OPSIZE_LONG;
1228 decoded->dst.addr_mode = MODE_AREG; 1299 decoded->dst.addr_mode = MODE_AREG;
1229 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); 1300 decoded->dst.params.regs.pri = m68k_reg_quick_field(opcode);
1230 istream = m68k_decode_op(istream, OPSIZE_LONG, &(decoded->src)); 1301 address = m68k_decode_op(opcode, address, fetch, data, OPSIZE_LONG, &(decoded->src));
1231 if (!istream) { 1302 if (address == INVALID_ADDRESS) {
1232 decoded->op = M68K_INVALID; 1303 decoded->op = M68K_INVALID;
1233 break; 1304 break;
1234 } 1305 }
1235 } else { 1306 } else {
1236 decoded->extra.size = size; 1307 decoded->extra.size = size;
1237 decoded->src.addr_mode = MODE_REG; 1308 decoded->src.addr_mode = MODE_REG;
1238 decoded->src.params.regs.pri = m68k_reg_quick_field(*istream); 1309 decoded->src.params.regs.pri = m68k_reg_quick_field(opcode);
1239 istream = m68k_decode_op(istream, size, &(decoded->dst)); 1310 address = m68k_decode_op(opcode, address, fetch, data, size, &(decoded->dst));
1240 if (!istream || !m68k_valid_full_arith_dst(&decoded->dst)) { 1311 if (address == INVALID_ADDRESS || !m68k_valid_full_arith_dst(&decoded->dst)) {
1241 decoded->op = M68K_INVALID; 1312 decoded->op = M68K_INVALID;
1242 break; 1313 break;
1243 } 1314 }
1244 } 1315 }
1245 } else { 1316 } else {
1246 //SUBX 1317 //SUBX
1247 decoded->op = M68K_SUBX; 1318 decoded->op = M68K_SUBX;
1248 decoded->extra.size = size; 1319 decoded->extra.size = size;
1249 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); 1320 decoded->dst.params.regs.pri = m68k_reg_quick_field(opcode);
1250 decoded->src.params.regs.pri = *istream & 0x7; 1321 decoded->src.params.regs.pri = opcode & 0x7;
1251 if (*istream & 0x8) { 1322 if (opcode & 0x8) {
1252 decoded->dst.addr_mode = decoded->src.addr_mode = MODE_AREG_PREDEC; 1323 decoded->dst.addr_mode = decoded->src.addr_mode = MODE_AREG_PREDEC;
1253 } else { 1324 } else {
1254 decoded->dst.addr_mode = decoded->src.addr_mode = MODE_REG; 1325 decoded->dst.addr_mode = decoded->src.addr_mode = MODE_REG;
1255 } 1326 }
1256 } 1327 }
1261 decoded->dst.addr_mode = MODE_AREG; 1332 decoded->dst.addr_mode = MODE_AREG;
1262 } else { 1333 } else {
1263 decoded->extra.size = size; 1334 decoded->extra.size = size;
1264 decoded->dst.addr_mode = MODE_REG; 1335 decoded->dst.addr_mode = MODE_REG;
1265 } 1336 }
1266 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); 1337 decoded->dst.params.regs.pri = m68k_reg_quick_field(opcode);
1267 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->src)); 1338 address = m68k_decode_op(opcode, address, fetch, data, decoded->extra.size, &(decoded->src));
1268 if (!istream || (decoded->src.addr_mode == MODE_AREG && decoded->extra.size == OPSIZE_BYTE)) { 1339 if (address == INVALID_ADDRESS || (decoded->src.addr_mode == MODE_AREG && decoded->extra.size == OPSIZE_BYTE)) {
1269 decoded->op = M68K_INVALID; 1340 decoded->op = M68K_INVALID;
1270 break; 1341 break;
1271 } 1342 }
1272 } 1343 }
1273 break; 1344 break;
1274 case A_LINE: 1345 case A_LINE:
1275 decoded->op = M68K_A_LINE_TRAP; 1346 decoded->op = M68K_A_LINE_TRAP;
1276 break; 1347 break;
1277 case CMP_XOR: 1348 case CMP_XOR:
1278 size = (*istream >> 6) & 0x3; 1349 size = (opcode >> 6) & 0x3;
1279 decoded->op = M68K_CMP; 1350 decoded->op = M68K_CMP;
1280 if (*istream & 0x100) { 1351 if (opcode & 0x100) {
1281 //CMPM or CMPA.l or EOR 1352 //CMPM or CMPA.l or EOR
1282 if (size == OPSIZE_INVALID) { 1353 if (size == OPSIZE_INVALID) {
1283 decoded->extra.size = OPSIZE_LONG; 1354 decoded->extra.size = OPSIZE_LONG;
1284 decoded->dst.addr_mode = MODE_AREG; 1355 decoded->dst.addr_mode = MODE_AREG;
1285 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); 1356 decoded->dst.params.regs.pri = m68k_reg_quick_field(opcode);
1286 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->src)); 1357 address = m68k_decode_op(opcode, address, fetch, data, decoded->extra.size, &(decoded->src));
1287 if (!istream) { 1358 if (address == INVALID_ADDRESS) {
1288 decoded->op = M68K_INVALID; 1359 decoded->op = M68K_INVALID;
1289 break; 1360 break;
1290 } 1361 }
1291 } else { 1362 } else {
1292 reg = m68k_reg_quick_field(*istream); 1363 reg = m68k_reg_quick_field(opcode);
1293 istream = m68k_decode_op(istream, size, &(decoded->dst)); 1364 address = m68k_decode_op(opcode, address, fetch, data, size, &(decoded->dst));
1294 if (!istream) { 1365 if (address == INVALID_ADDRESS) {
1295 decoded->op = M68K_INVALID; 1366 decoded->op = M68K_INVALID;
1296 break; 1367 break;
1297 } 1368 }
1298 decoded->extra.size = size; 1369 decoded->extra.size = size;
1299 if (decoded->dst.addr_mode == MODE_AREG) { 1370 if (decoded->dst.addr_mode == MODE_AREG) {
1318 decoded->dst.addr_mode = MODE_AREG; 1389 decoded->dst.addr_mode = MODE_AREG;
1319 } else { 1390 } else {
1320 decoded->extra.size = size; 1391 decoded->extra.size = size;
1321 decoded->dst.addr_mode = MODE_REG; 1392 decoded->dst.addr_mode = MODE_REG;
1322 } 1393 }
1323 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); 1394 decoded->dst.params.regs.pri = m68k_reg_quick_field(opcode);
1324 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->src)); 1395 address = m68k_decode_op(opcode, address, fetch, data, decoded->extra.size, &(decoded->src));
1325 if (!istream || (decoded->src.addr_mode == MODE_AREG && decoded->extra.size == OPSIZE_BYTE)) { 1396 if (address == INVALID_ADDRESS || (decoded->src.addr_mode == MODE_AREG && decoded->extra.size == OPSIZE_BYTE)) {
1326 decoded->op = M68K_INVALID; 1397 decoded->op = M68K_INVALID;
1327 break; 1398 break;
1328 } 1399 }
1329 } 1400 }
1330 break; 1401 break;
1336 //10001 -one of each 1407 //10001 -one of each
1337 //AND opmodes: 1408 //AND opmodes:
1338 //operand order bit + 2 size bits (00 - 10) 1409 //operand order bit + 2 size bits (00 - 10)
1339 //no address register direct addressing 1410 //no address register direct addressing
1340 //data register direct not allowed when <ea> is the source (operand order bit of 1) 1411 //data register direct not allowed when <ea> is the source (operand order bit of 1)
1341 if (*istream & 0x100) { 1412 if (opcode & 0x100) {
1342 if ((*istream & 0xC0) == 0xC0) { 1413 if ((opcode & 0xC0) == 0xC0) {
1343 decoded->op = M68K_MULS; 1414 decoded->op = M68K_MULS;
1344 decoded->extra.size = OPSIZE_WORD; 1415 decoded->extra.size = OPSIZE_WORD;
1345 decoded->dst.addr_mode = MODE_REG; 1416 decoded->dst.addr_mode = MODE_REG;
1346 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); 1417 decoded->dst.params.regs.pri = m68k_reg_quick_field(opcode);
1347 istream = m68k_decode_op(istream, OPSIZE_WORD, &(decoded->src)); 1418 address = m68k_decode_op(opcode, address, fetch, data, OPSIZE_WORD, &(decoded->src));
1348 if (!istream || decoded->src.addr_mode == MODE_AREG) { 1419 if (address == INVALID_ADDRESS || decoded->src.addr_mode == MODE_AREG) {
1349 decoded->op = M68K_INVALID; 1420 decoded->op = M68K_INVALID;
1350 break; 1421 break;
1351 } 1422 }
1352 } else if(!(*istream & 0xF0)) { 1423 } else if(!(opcode & 0xF0)) {
1353 decoded->op = M68K_ABCD; 1424 decoded->op = M68K_ABCD;
1354 decoded->extra.size = OPSIZE_BYTE; 1425 decoded->extra.size = OPSIZE_BYTE;
1355 decoded->src.params.regs.pri = *istream & 0x7; 1426 decoded->src.params.regs.pri = opcode & 0x7;
1356 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); 1427 decoded->dst.params.regs.pri = m68k_reg_quick_field(opcode);
1357 decoded->dst.addr_mode = decoded->src.addr_mode = (*istream & 8) ? MODE_AREG_PREDEC : MODE_REG; 1428 decoded->dst.addr_mode = decoded->src.addr_mode = (opcode & 8) ? MODE_AREG_PREDEC : MODE_REG;
1358 } else if(!(*istream & 0x30)) { 1429 } else if(!(opcode & 0x30)) {
1359 decoded->op = M68K_EXG; 1430 decoded->op = M68K_EXG;
1360 decoded->extra.size = OPSIZE_LONG; 1431 decoded->extra.size = OPSIZE_LONG;
1361 decoded->src.params.regs.pri = m68k_reg_quick_field(*istream); 1432 decoded->src.params.regs.pri = m68k_reg_quick_field(opcode);
1362 decoded->dst.params.regs.pri = *istream & 0x7; 1433 decoded->dst.params.regs.pri = opcode & 0x7;
1363 if (*istream & 0x8) { 1434 if (opcode & 0x8) {
1364 if (*istream & 0x80) { 1435 if (opcode & 0x80) {
1365 decoded->src.addr_mode = MODE_REG; 1436 decoded->src.addr_mode = MODE_REG;
1366 decoded->dst.addr_mode = MODE_AREG; 1437 decoded->dst.addr_mode = MODE_AREG;
1367 } else { 1438 } else {
1368 decoded->src.addr_mode = decoded->dst.addr_mode = MODE_AREG; 1439 decoded->src.addr_mode = decoded->dst.addr_mode = MODE_AREG;
1369 } 1440 }
1370 } else if (*istream & 0x40) { 1441 } else if (opcode & 0x40) {
1371 decoded->src.addr_mode = decoded->dst.addr_mode = MODE_REG; 1442 decoded->src.addr_mode = decoded->dst.addr_mode = MODE_REG;
1372 } else { 1443 } else {
1373 decoded->op = M68K_INVALID; 1444 decoded->op = M68K_INVALID;
1374 break; 1445 break;
1375 } 1446 }
1376 } else { 1447 } else {
1377 decoded->op = M68K_AND; 1448 decoded->op = M68K_AND;
1378 decoded->extra.size = (*istream >> 6) & 0x3; 1449 decoded->extra.size = (opcode >> 6) & 0x3;
1379 decoded->src.addr_mode = MODE_REG; 1450 decoded->src.addr_mode = MODE_REG;
1380 decoded->src.params.regs.pri = m68k_reg_quick_field(*istream); 1451 decoded->src.params.regs.pri = m68k_reg_quick_field(opcode);
1381 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->dst)); 1452 address = m68k_decode_op(opcode, address, fetch, data, decoded->extra.size, &(decoded->dst));
1382 if (!istream || !m68k_valid_full_arith_dst(&(decoded->dst))) { 1453 if (address == INVALID_ADDRESS || !m68k_valid_full_arith_dst(&(decoded->dst))) {
1383 decoded->op = M68K_INVALID; 1454 decoded->op = M68K_INVALID;
1384 break; 1455 break;
1385 } 1456 }
1386 } 1457 }
1387 } else { 1458 } else {
1388 if ((*istream & 0xC0) == 0xC0) { 1459 if ((opcode & 0xC0) == 0xC0) {
1389 decoded->op = M68K_MULU; 1460 decoded->op = M68K_MULU;
1390 decoded->extra.size = OPSIZE_WORD; 1461 decoded->extra.size = OPSIZE_WORD;
1391 decoded->dst.addr_mode = MODE_REG; 1462 decoded->dst.addr_mode = MODE_REG;
1392 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); 1463 decoded->dst.params.regs.pri = m68k_reg_quick_field(opcode);
1393 istream = m68k_decode_op(istream, OPSIZE_WORD, &(decoded->src)); 1464 address = m68k_decode_op(opcode, address, fetch, data, OPSIZE_WORD, &(decoded->src));
1394 if (!istream || decoded->src.addr_mode == MODE_AREG) { 1465 if (address == INVALID_ADDRESS || decoded->src.addr_mode == MODE_AREG) {
1395 decoded->op = M68K_INVALID; 1466 decoded->op = M68K_INVALID;
1396 break; 1467 break;
1397 } 1468 }
1398 } else { 1469 } else {
1399 decoded->op = M68K_AND; 1470 decoded->op = M68K_AND;
1400 decoded->extra.size = (*istream >> 6) & 0x3; 1471 decoded->extra.size = (opcode >> 6) & 0x3;
1401 decoded->dst.addr_mode = MODE_REG; 1472 decoded->dst.addr_mode = MODE_REG;
1402 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); 1473 decoded->dst.params.regs.pri = m68k_reg_quick_field(opcode);
1403 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->src)); 1474 address = m68k_decode_op(opcode, address, fetch, data, decoded->extra.size, &(decoded->src));
1404 if (!istream || decoded->src.addr_mode == MODE_AREG) { 1475 if (address == INVALID_ADDRESS || decoded->src.addr_mode == MODE_AREG) {
1405 decoded->op = M68K_INVALID; 1476 decoded->op = M68K_INVALID;
1406 break; 1477 break;
1407 } 1478 }
1408 } 1479 }
1409 } 1480 }
1410 break; 1481 break;
1411 case ADD_ADDX: 1482 case ADD_ADDX:
1412 size = (*istream >> 6) & 0x3; 1483 size = (opcode >> 6) & 0x3;
1413 decoded->op = M68K_ADD; 1484 decoded->op = M68K_ADD;
1414 if (*istream & 0x100) { 1485 if (opcode & 0x100) {
1415 //<ea> destination, ADDA.l or ADDX 1486 //<ea> destination, ADDA.l or ADDX
1416 if (*istream & 0x30 || size == OPSIZE_INVALID) { 1487 if (opcode & 0x30 || size == OPSIZE_INVALID) {
1417 if (size == OPSIZE_INVALID) { 1488 if (size == OPSIZE_INVALID) {
1418 //ADDA.l 1489 //ADDA.l
1419 decoded->extra.size = OPSIZE_LONG; 1490 decoded->extra.size = OPSIZE_LONG;
1420 decoded->dst.addr_mode = MODE_AREG; 1491 decoded->dst.addr_mode = MODE_AREG;
1421 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); 1492 decoded->dst.params.regs.pri = m68k_reg_quick_field(opcode);
1422 istream = m68k_decode_op(istream, OPSIZE_LONG, &(decoded->src)); 1493 address = m68k_decode_op(opcode, address, fetch, data, OPSIZE_LONG, &(decoded->src));
1423 if (!istream) { 1494 if (address == INVALID_ADDRESS) {
1424 decoded->op = M68K_INVALID; 1495 decoded->op = M68K_INVALID;
1425 break; 1496 break;
1426 } 1497 }
1427 } else { 1498 } else {
1428 decoded->extra.size = size; 1499 decoded->extra.size = size;
1429 decoded->src.addr_mode = MODE_REG; 1500 decoded->src.addr_mode = MODE_REG;
1430 decoded->src.params.regs.pri = m68k_reg_quick_field(*istream); 1501 decoded->src.params.regs.pri = m68k_reg_quick_field(opcode);
1431 istream = m68k_decode_op(istream, size, &(decoded->dst)); 1502 address = m68k_decode_op(opcode, address, fetch, data, size, &(decoded->dst));
1432 if (!istream || !m68k_valid_full_arith_dst(&decoded->dst)) { 1503 if (address == INVALID_ADDRESS || !m68k_valid_full_arith_dst(&decoded->dst)) {
1433 decoded->op = M68K_INVALID; 1504 decoded->op = M68K_INVALID;
1434 break; 1505 break;
1435 } 1506 }
1436 } 1507 }
1437 } else { 1508 } else {
1438 //ADDX 1509 //ADDX
1439 decoded->op = M68K_ADDX; 1510 decoded->op = M68K_ADDX;
1440 decoded->extra.size = size; 1511 decoded->extra.size = size;
1441 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); 1512 decoded->dst.params.regs.pri = m68k_reg_quick_field(opcode);
1442 decoded->src.params.regs.pri = *istream & 0x7; 1513 decoded->src.params.regs.pri = opcode & 0x7;
1443 if (*istream & 0x8) { 1514 if (opcode & 0x8) {
1444 decoded->dst.addr_mode = decoded->src.addr_mode = MODE_AREG_PREDEC; 1515 decoded->dst.addr_mode = decoded->src.addr_mode = MODE_AREG_PREDEC;
1445 } else { 1516 } else {
1446 decoded->dst.addr_mode = decoded->src.addr_mode = MODE_REG; 1517 decoded->dst.addr_mode = decoded->src.addr_mode = MODE_REG;
1447 } 1518 }
1448 } 1519 }
1453 decoded->dst.addr_mode = MODE_AREG; 1524 decoded->dst.addr_mode = MODE_AREG;
1454 } else { 1525 } else {
1455 decoded->extra.size = size; 1526 decoded->extra.size = size;
1456 decoded->dst.addr_mode = MODE_REG; 1527 decoded->dst.addr_mode = MODE_REG;
1457 } 1528 }
1458 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); 1529 decoded->dst.params.regs.pri = m68k_reg_quick_field(opcode);
1459 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->src)); 1530 address = m68k_decode_op(opcode, address, fetch, data, decoded->extra.size, &(decoded->src));
1460 if (!istream || (decoded->src.addr_mode == MODE_AREG && decoded->extra.size == OPSIZE_BYTE)) { 1531 if (address == INVALID_ADDRESS || (decoded->src.addr_mode == MODE_AREG && decoded->extra.size == OPSIZE_BYTE)) {
1461 decoded->op = M68K_INVALID; 1532 decoded->op = M68K_INVALID;
1462 break; 1533 break;
1463 } 1534 }
1464 } 1535 }
1465 break; 1536 break;
1466 case SHIFT_ROTATE: 1537 case SHIFT_ROTATE:
1467 if ((*istream & 0x8C0) == 0xC0) { 1538 if ((opcode & 0x8C0) == 0xC0) {
1468 switch((*istream >> 8) & 0x7) 1539 switch((opcode >> 8) & 0x7)
1469 { 1540 {
1470 case 0: 1541 case 0:
1471 decoded->op = M68K_ASR; 1542 decoded->op = M68K_ASR;
1472 break; 1543 break;
1473 case 1: 1544 case 1:
1491 case 7: 1562 case 7:
1492 decoded->op = M68K_ROL; 1563 decoded->op = M68K_ROL;
1493 break; 1564 break;
1494 } 1565 }
1495 decoded->extra.size = OPSIZE_WORD; 1566 decoded->extra.size = OPSIZE_WORD;
1496 istream = m68k_decode_op(istream, OPSIZE_WORD, &(decoded->dst)); 1567 address = m68k_decode_op(opcode, address, fetch, data, OPSIZE_WORD, &(decoded->dst));
1497 if (!istream || !m68k_valid_full_arith_dst(&decoded->dst)) { 1568 if (address == INVALID_ADDRESS || !m68k_valid_full_arith_dst(&decoded->dst)) {
1498 decoded->op = M68K_INVALID; 1569 decoded->op = M68K_INVALID;
1499 break; 1570 break;
1500 } 1571 }
1501 } else if((*istream & 0xC0) != 0xC0) { 1572 } else if((opcode & 0xC0) != 0xC0) {
1502 switch(((*istream >> 2) & 0x6) | ((*istream >> 8) & 1)) 1573 switch(((opcode >> 2) & 0x6) | ((opcode >> 8) & 1))
1503 { 1574 {
1504 case 0: 1575 case 0:
1505 decoded->op = M68K_ASR; 1576 decoded->op = M68K_ASR;
1506 break; 1577 break;
1507 case 1: 1578 case 1:
1524 break; 1595 break;
1525 case 7: 1596 case 7:
1526 decoded->op = M68K_ROL; 1597 decoded->op = M68K_ROL;
1527 break; 1598 break;
1528 } 1599 }
1529 decoded->extra.size = (*istream >> 6) & 0x3; 1600 decoded->extra.size = (opcode >> 6) & 0x3;
1530 immed = (*istream >> 9) & 0x7; 1601 immed = (opcode >> 9) & 0x7;
1531 if (*istream & 0x20) { 1602 if (opcode & 0x20) {
1532 decoded->src.addr_mode = MODE_REG; 1603 decoded->src.addr_mode = MODE_REG;
1533 decoded->src.params.regs.pri = immed; 1604 decoded->src.params.regs.pri = immed;
1534 } else { 1605 } else {
1535 decoded->src.addr_mode = MODE_IMMEDIATE; 1606 decoded->src.addr_mode = MODE_IMMEDIATE;
1536 if (!immed) { 1607 if (!immed) {
1538 } 1609 }
1539 decoded->src.params.immed = immed; 1610 decoded->src.params.immed = immed;
1540 decoded->variant = VAR_QUICK; 1611 decoded->variant = VAR_QUICK;
1541 } 1612 }
1542 decoded->dst.addr_mode = MODE_REG; 1613 decoded->dst.addr_mode = MODE_REG;
1543 decoded->dst.params.regs.pri = *istream & 0x7; 1614 decoded->dst.params.regs.pri = opcode & 0x7;
1544 1615
1545 } else { 1616 } else {
1546 #ifdef M68020 1617 #ifdef M68020
1547 //TODO: Implement bitfield instructions for M68020+ support 1618 //TODO: Implement bitfield instructions for M68020+ support
1548 switch (*istream >> 8 & 7) 1619 switch (opcode >> 8 & 7)
1549 { 1620 {
1550 case 0: 1621 case 0:
1551 decoded->op = M68K_BFTST; //<ea> 1622 decoded->op = M68K_BFTST; //<ea>
1552 break; 1623 break;
1553 case 1: 1624 case 1:
1570 break; 1641 break;
1571 case 7: 1642 case 7:
1572 decoded->op = M68K_BFINS; //Dn, <ea> 1643 decoded->op = M68K_BFINS; //Dn, <ea>
1573 break; 1644 break;
1574 } 1645 }
1575 opmode = *istream >> 3 & 0x7; 1646 opmode = opcode >> 3 & 0x7;
1576 reg = *istream & 0x7; 1647 reg = opcode & 0x7;
1577 m68k_op_info *ea, *other; 1648 m68k_op_info *ea, *other;
1578 if (decoded->op == M68K_BFEXTU || decoded->op == M68K_BFEXTS || decoded->op == M68K_BFFFO) 1649 if (decoded->op == M68K_BFEXTU || decoded->op == M68K_BFEXTS || decoded->op == M68K_BFFFO)
1579 { 1650 {
1580 ea = &(decoded->src); 1651 ea = &(decoded->src);
1581 other = &(decoded->dst); 1652 other = &(decoded->dst);
1582 } else { 1653 } else {
1583 ea = &(decoded->dst); 1654 ea = &(decoded->dst);
1584 other = &(decoded->dst); 1655 other = &(decoded->dst);
1585 } 1656 }
1586 if (*istream & 0x100) 1657 if (opcode & 0x100)
1587 { 1658 {
1588 immed = *(istream++); 1659 immed = fetch(address, data);
1660 address += 2;
1589 other->addr_mode = MODE_REG; 1661 other->addr_mode = MODE_REG;
1590 other->params.regs.pri = immed >> 12 & 0x7; 1662 other->params.regs.pri = immed >> 12 & 0x7;
1591 } else { 1663 } else {
1592 immed = *(istream++); 1664 immed = fetch(address, data);
1665 address += 2;
1593 } 1666 }
1594 decoded->extra.size = OPSIZE_UNSIZED; 1667 decoded->extra.size = OPSIZE_UNSIZED;
1595 istream = m68k_decode_op_ex(istream, opmode, reg, decoded->extra.size, ea); 1668 address = m68k_decode_op_ex(opcode, address, fetch, data, opmode, reg, decoded->extra.size, ea);
1596 ea->addr_mode |= M68K_FLAG_BITFIELD; 1669 ea->addr_mode |= M68K_FLAG_BITFIELD;
1597 ea->bitfield = immed & 0xFFF; 1670 ea->bitfield = immed & 0xFFF;
1598 #endif 1671 #endif
1599 } 1672 }
1600 break; 1673 break;
1602 //TODO: Decode FPU instructions for members of the 68K family with an FPU 1675 //TODO: Decode FPU instructions for members of the 68K family with an FPU
1603 decoded->op = M68K_F_LINE_TRAP; 1676 decoded->op = M68K_F_LINE_TRAP;
1604 break; 1677 break;
1605 } 1678 }
1606 if (decoded->op == M68K_INVALID) { 1679 if (decoded->op == M68K_INVALID) {
1607 decoded->src.params.immed = *start; 1680 decoded->src.params.immed = opcode;
1608 decoded->bytes = 2; 1681 decoded->bytes = 2;
1609 return start + 1; 1682 return start_address + 2;
1610 } 1683 }
1611 decoded->bytes = 2 * (istream + 1 - start); 1684 decoded->bytes = address - start_address;
1612 return istream+1; 1685 return address;
1613 } 1686 }
1614 1687
1615 uint32_t m68k_branch_target(m68kinst * inst, uint32_t *dregs, uint32_t *aregs) 1688 uint32_t m68k_branch_target(m68kinst * inst, uint32_t *dregs, uint32_t *aregs)
1616 { 1689 {
1617 if(inst->op == M68K_BCC || inst->op == M68K_BSR || inst->op == M68K_DBCC) { 1690 if(inst->op == M68K_BCC || inst->op == M68K_BSR || inst->op == M68K_DBCC) {
2607 } 2680 }
2608 return ret; 2681 return ret;
2609 #endif 2682 #endif
2610 default: 2683 default:
2611 size = decoded->extra.size; 2684 size = decoded->extra.size;
2612 uint8_t is_quick = decoded->variant == VAR_QUICK && decoded->op != M68K_ASL && decoded->op != M68K_ASR 2685 uint8_t is_quick = decoded->variant == VAR_QUICK && decoded->op != M68K_ASL && decoded->op != M68K_ASR
2613 && decoded->op != M68K_LSL && decoded->op != M68K_LSR && decoded->op != M68K_ROXR && decoded->op != M68K_ROXL 2686 && decoded->op != M68K_LSL && decoded->op != M68K_LSR && decoded->op != M68K_ROXR && decoded->op != M68K_ROXL
2614 && decoded->op != M68K_ROR && decoded->op != M68K_ROL; 2687 && decoded->op != M68K_ROR && decoded->op != M68K_ROL;
2615 ret = sprintf(dst, "%s%s%s", 2688 ret = sprintf(dst, "%s%s%s",
2616 mnemonics[decoded->op], 2689 mnemonics[decoded->op],
2617 is_quick ? "q" : (decoded->variant == VAR_IMMEDIATE ? "i" : ""), 2690 is_quick ? "q" : (decoded->variant == VAR_IMMEDIATE ? "i" : ""),