Mercurial > repos > blastem
comparison m68k_core.c @ 588:963d5901f583
Move translate_m68k_movem to m68k_core.c
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Sat, 08 Mar 2014 00:15:09 -0800 |
parents | 55c5b0f913ce |
children | 60a06c025103 |
comparison
equal
deleted
inserted
replaced
587:55c5b0f913ce | 588:963d5901f583 |
---|---|
345 reg = opts->gen.scratch1; | 345 reg = opts->gen.scratch1; |
346 areg_to_native(opts, inst->src.params.regs.pri, reg); | 346 areg_to_native(opts, inst->src.params.regs.pri, reg); |
347 } | 347 } |
348 native_to_areg(opts, reg, 8); | 348 native_to_areg(opts, reg, 8); |
349 } | 349 } |
350 } | |
351 | |
352 void translate_m68k_movem(m68k_options * opts, m68kinst * inst) | |
353 { | |
354 code_info *code = &opts->gen.code; | |
355 int8_t bit,reg,sec_reg; | |
356 uint8_t early_cycles; | |
357 if(inst->src.addr_mode == MODE_REG) { | |
358 //reg to mem | |
359 early_cycles = 8; | |
360 int8_t dir; | |
361 switch (inst->dst.addr_mode) | |
362 { | |
363 case MODE_AREG_INDIRECT: | |
364 case MODE_AREG_PREDEC: | |
365 areg_to_native(opts, inst->dst.params.regs.pri, opts->gen.scratch2); | |
366 break; | |
367 case MODE_AREG_DISPLACE: | |
368 early_cycles += BUS; | |
369 calc_areg_displace(opts, &inst->dst, opts->gen.scratch2); | |
370 break; | |
371 case MODE_AREG_INDEX_DISP8: | |
372 early_cycles += 6; | |
373 calc_areg_index_disp8(opts, &inst->dst, opts->gen.scratch2); | |
374 break; | |
375 case MODE_PC_DISPLACE: | |
376 early_cycles += BUS; | |
377 ldi_native(opts, inst->dst.params.regs.displacement + inst->address+2, opts->gen.scratch2); | |
378 break; | |
379 case MODE_PC_INDEX_DISP8: | |
380 early_cycles += 6; | |
381 ldi_native(opts, inst->address+2, opts->gen.scratch2); | |
382 calc_index_disp8(opts, &inst->dst, opts->gen.scratch2); | |
383 case MODE_ABSOLUTE: | |
384 early_cycles += 4; | |
385 case MODE_ABSOLUTE_SHORT: | |
386 early_cycles += 4; | |
387 ldi_native(opts, inst->dst.params.immed, opts->gen.scratch2); | |
388 break; | |
389 default: | |
390 m68k_disasm(inst, disasm_buf); | |
391 printf("%X: %s\naddress mode %d not implemented (movem dst)\n", inst->address, disasm_buf, inst->dst.addr_mode); | |
392 exit(1); | |
393 } | |
394 if (inst->dst.addr_mode == MODE_AREG_PREDEC) { | |
395 reg = 15; | |
396 dir = -1; | |
397 } else { | |
398 reg = 0; | |
399 dir = 1; | |
400 } | |
401 cycles(&opts->gen, early_cycles); | |
402 for(bit=0; reg < 16 && reg >= 0; reg += dir, bit++) { | |
403 if (inst->src.params.immed & (1 << bit)) { | |
404 if (inst->dst.addr_mode == MODE_AREG_PREDEC) { | |
405 subi_native(opts, (inst->extra.size == OPSIZE_LONG) ? 4 : 2, opts->gen.scratch2); | |
406 } | |
407 push_native(opts, opts->gen.scratch2); | |
408 if (reg > 7) { | |
409 areg_to_native(opts, reg-8, opts->gen.scratch1); | |
410 } else { | |
411 dreg_to_native(opts, reg, opts->gen.scratch1); | |
412 } | |
413 if (inst->extra.size == OPSIZE_LONG) { | |
414 call(code, opts->write_32_lowfirst); | |
415 } else { | |
416 call(code, opts->write_16); | |
417 } | |
418 pop_native(opts, opts->gen.scratch2); | |
419 if (inst->dst.addr_mode != MODE_AREG_PREDEC) { | |
420 addi_native(opts, (inst->extra.size == OPSIZE_LONG) ? 4 : 2, opts->gen.scratch2); | |
421 } | |
422 } | |
423 } | |
424 if (inst->dst.addr_mode == MODE_AREG_PREDEC) { | |
425 native_to_areg(opts, opts->gen.scratch2, inst->dst.params.regs.pri); | |
426 } | |
427 } else { | |
428 //mem to reg | |
429 early_cycles = 4; | |
430 switch (inst->src.addr_mode) | |
431 { | |
432 case MODE_AREG_INDIRECT: | |
433 case MODE_AREG_POSTINC: | |
434 areg_to_native(opts, inst->src.params.regs.pri, opts->gen.scratch1); | |
435 break; | |
436 case MODE_AREG_DISPLACE: | |
437 early_cycles += BUS; | |
438 reg = opts->gen.scratch2; | |
439 calc_areg_displace(opts, &inst->src, opts->gen.scratch1); | |
440 break; | |
441 case MODE_AREG_INDEX_DISP8: | |
442 early_cycles += 6; | |
443 calc_areg_index_disp8(opts, &inst->src, opts->gen.scratch1); | |
444 break; | |
445 case MODE_PC_DISPLACE: | |
446 early_cycles += BUS; | |
447 ldi_native(opts, inst->src.params.regs.displacement + inst->address+2, opts->gen.scratch1); | |
448 break; | |
449 case MODE_PC_INDEX_DISP8: | |
450 early_cycles += 6; | |
451 ldi_native(opts, inst->address+2, opts->gen.scratch1); | |
452 calc_index_disp8(opts, &inst->src, opts->gen.scratch1); | |
453 break; | |
454 case MODE_ABSOLUTE: | |
455 early_cycles += 4; | |
456 case MODE_ABSOLUTE_SHORT: | |
457 early_cycles += 4; | |
458 ldi_native(opts, inst->src.params.immed, opts->gen.scratch1); | |
459 break; | |
460 default: | |
461 m68k_disasm(inst, disasm_buf); | |
462 printf("%X: %s\naddress mode %d not implemented (movem src)\n", inst->address, disasm_buf, inst->src.addr_mode); | |
463 exit(1); | |
464 } | |
465 cycles(&opts->gen, early_cycles); | |
466 for(reg = 0; reg < 16; reg ++) { | |
467 if (inst->dst.params.immed & (1 << reg)) { | |
468 push_native(opts, opts->gen.scratch1); | |
469 if (inst->extra.size == OPSIZE_LONG) { | |
470 call(code, opts->read_32); | |
471 } else { | |
472 call(code, opts->read_16); | |
473 } | |
474 if (inst->extra.size == OPSIZE_WORD) { | |
475 sign_extend16_native(opts, opts->gen.scratch1); | |
476 } | |
477 if (reg > 7) { | |
478 native_to_areg(opts, opts->gen.scratch1, reg-8); | |
479 } else { | |
480 native_to_dreg(opts, opts->gen.scratch1, reg); | |
481 } | |
482 pop_native(opts, opts->gen.scratch1); | |
483 addi_native(opts, (inst->extra.size == OPSIZE_LONG) ? 4 : 2, opts->gen.scratch1); | |
484 } | |
485 } | |
486 if (inst->src.addr_mode == MODE_AREG_POSTINC) { | |
487 native_to_areg(opts, opts->gen.scratch1, inst->src.params.regs.pri); | |
488 } | |
489 } | |
490 //prefetch | |
491 cycles(&opts->gen, 4); | |
350 } | 492 } |
351 | 493 |
352 void translate_m68k_nop(m68k_options *opts, m68kinst *inst) | 494 void translate_m68k_nop(m68k_options *opts, m68kinst *inst) |
353 { | 495 { |
354 cycles(&opts->gen, BUS); | 496 cycles(&opts->gen, BUS); |