Mercurial > repos > blastem
comparison m68k_core.c @ 582:c05fcbfe1b1a
Refactored translate_m68k so that it contains no host-cpu specific code and moved it to m68k_core.c
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Fri, 07 Mar 2014 17:42:29 -0800 |
parents | 9f40aa5243c2 |
children | b6713c1b6f55 |
comparison
equal
deleted
inserted
replaced
581:9f40aa5243c2 | 582:c05fcbfe1b1a |
---|---|
324 ldi_native(opts, inst->src.params.immed + VECTOR_TRAP_0, opts->gen.scratch2); | 324 ldi_native(opts, inst->src.params.immed + VECTOR_TRAP_0, opts->gen.scratch2); |
325 ldi_native(opts, inst->address+2, opts->gen.scratch1); | 325 ldi_native(opts, inst->address+2, opts->gen.scratch1); |
326 jmp(code, opts->trap); | 326 jmp(code, opts->trap); |
327 } | 327 } |
328 | 328 |
329 void translate_m68k_move_usp(m68k_options *opts, m68kinst *inst) | |
330 { | |
331 cycles(&opts->gen, BUS); | |
332 int8_t reg; | |
333 if (inst->src.addr_mode == MODE_UNUSED) { | |
334 reg = native_reg(&inst->dst, opts); | |
335 if (reg < 0) { | |
336 reg = opts->gen.scratch1; | |
337 } | |
338 areg_to_native(opts, 8, reg); | |
339 if (reg == opts->gen.scratch1) { | |
340 native_to_areg(opts, opts->gen.scratch1, inst->dst.params.regs.pri); | |
341 } | |
342 } else { | |
343 reg = native_reg(&inst->src, opts); | |
344 if (reg < 0) { | |
345 reg = opts->gen.scratch1; | |
346 areg_to_native(opts, inst->src.params.regs.pri, reg); | |
347 } | |
348 native_to_areg(opts, reg, 8); | |
349 } | |
350 } | |
351 | |
352 void translate_m68k_nop(m68k_options *opts, m68kinst *inst) | |
353 { | |
354 cycles(&opts->gen, BUS); | |
355 } | |
356 | |
329 void swap_ssp_usp(m68k_options * opts) | 357 void swap_ssp_usp(m68k_options * opts) |
330 { | 358 { |
331 areg_to_native(opts, 7, opts->gen.scratch2); | 359 areg_to_native(opts, 7, opts->gen.scratch2); |
332 areg_to_native(opts, 8, opts->aregs[7]); | 360 areg_to_native(opts, 8, opts->aregs[7]); |
333 native_to_areg(opts, opts->gen.scratch2, 8); | 361 native_to_areg(opts, opts->gen.scratch2, 8); |
430 { | 458 { |
431 m68k_options * opts = context->options; | 459 m68k_options * opts = context->options; |
432 process_deferred(&opts->gen.deferred, context, (native_addr_func)get_native_from_context); | 460 process_deferred(&opts->gen.deferred, context, (native_addr_func)get_native_from_context); |
433 if (opts->gen.deferred) { | 461 if (opts->gen.deferred) { |
434 translate_m68k_stream(opts->gen.deferred->address, context); | 462 translate_m68k_stream(opts->gen.deferred->address, context); |
463 } | |
464 } | |
465 | |
466 typedef enum { | |
467 RAW_FUNC = 1, | |
468 BINARY_ARITH, | |
469 UNARY_ARITH, | |
470 OP_FUNC | |
471 } impl_type; | |
472 | |
473 typedef void (*raw_fun)(m68k_options * opts, m68kinst *inst); | |
474 typedef void (*op_fun)(m68k_options * opts, m68kinst *inst, host_ea *src_op, host_ea *dst_op); | |
475 | |
476 typedef struct { | |
477 union { | |
478 raw_fun raw; | |
479 uint32_t flag_mask; | |
480 op_fun op; | |
481 } impl; | |
482 impl_type itype; | |
483 } impl_info; | |
484 | |
485 #define RAW_IMPL(inst, fun) [inst] = { .impl = { .raw = fun }, .itype = RAW_FUNC } | |
486 #define OP_IMPL(inst, fun) [inst] = { .impl = { .op = fun }, .itype = OP_FUNC } | |
487 #define UNARY_IMPL(inst, mask) [inst] = { .impl = { .flag_mask = mask }, .itype = UNARY_ARITH } | |
488 #define BINARY_IMPL(inst, mask) [inst] = { .impl = { .flag_mask = mask}, .itype = BINARY_ARITH } | |
489 | |
490 impl_info m68k_impls[] = { | |
491 //math | |
492 BINARY_IMPL(M68K_ADD, X|N|Z|V|C), | |
493 BINARY_IMPL(M68K_SUB, X|N|Z|V|C), | |
494 //z flag is special cased for ADDX/SUBX | |
495 BINARY_IMPL(M68K_ADDX, X|N|V|C), | |
496 BINARY_IMPL(M68K_SUBX, X|N|V|C), | |
497 OP_IMPL(M68K_ABCD, translate_m68k_abcd_sbcd), | |
498 OP_IMPL(M68K_SBCD, translate_m68k_abcd_sbcd), | |
499 BINARY_IMPL(M68K_AND, N|Z|V0|C0), | |
500 BINARY_IMPL(M68K_EOR, N|Z|V0|C0), | |
501 BINARY_IMPL(M68K_OR, N|Z|V0|C0), | |
502 RAW_IMPL(M68K_CMP, translate_m68k_cmp), | |
503 OP_IMPL(M68K_DIVS, translate_m68k_div), | |
504 OP_IMPL(M68K_DIVU, translate_m68k_div), | |
505 OP_IMPL(M68K_MULS, translate_m68k_mul), | |
506 OP_IMPL(M68K_MULU, translate_m68k_mul), | |
507 RAW_IMPL(M68K_EXT, translate_m68k_ext), | |
508 UNARY_IMPL(M68K_NEG, X|N|Z|V|C), | |
509 OP_IMPL(M68K_NEGX, translate_m68k_negx), | |
510 UNARY_IMPL(M68K_NOT, X|N|Z|V|C), | |
511 UNARY_IMPL(M68K_TST, N|Z|V0|C0), | |
512 | |
513 //shift/rotate | |
514 OP_IMPL(M68K_ASL, translate_m68k_sl), | |
515 OP_IMPL(M68K_LSL, translate_m68k_sl), | |
516 OP_IMPL(M68K_ASR, translate_m68k_asr), | |
517 OP_IMPL(M68K_LSR, translate_m68k_lsr), | |
518 OP_IMPL(M68K_ROL, translate_m68k_rot), | |
519 OP_IMPL(M68K_ROR, translate_m68k_rot), | |
520 OP_IMPL(M68K_ROXL, translate_m68k_rot), | |
521 OP_IMPL(M68K_ROXR, translate_m68k_rot), | |
522 UNARY_IMPL(M68K_SWAP, N|Z|V0|C0), | |
523 | |
524 //bit | |
525 OP_IMPL(M68K_BCHG, translate_m68k_bit), | |
526 OP_IMPL(M68K_BCLR, translate_m68k_bit), | |
527 OP_IMPL(M68K_BSET, translate_m68k_bit), | |
528 OP_IMPL(M68K_BTST, translate_m68k_bit), | |
529 | |
530 //data movement | |
531 RAW_IMPL(M68K_MOVE, translate_m68k_move), | |
532 RAW_IMPL(M68K_MOVEM, translate_m68k_movem), | |
533 RAW_IMPL(M68K_MOVEP, translate_m68k_movep), | |
534 RAW_IMPL(M68K_MOVE_USP, translate_m68k_move_usp), | |
535 RAW_IMPL(M68K_LEA, translate_m68k_lea_pea), | |
536 RAW_IMPL(M68K_PEA, translate_m68k_lea_pea), | |
537 RAW_IMPL(M68K_CLR, translate_m68k_clr), | |
538 OP_IMPL(M68K_EXG, translate_m68k_exg), | |
539 RAW_IMPL(M68K_SCC, translate_m68k_scc), | |
540 | |
541 //function calls and branches | |
542 RAW_IMPL(M68K_BCC, translate_m68k_bcc), | |
543 RAW_IMPL(M68K_BSR, translate_m68k_bsr), | |
544 RAW_IMPL(M68K_DBCC, translate_m68k_dbcc), | |
545 RAW_IMPL(M68K_JMP, translate_m68k_jmp_jsr), | |
546 RAW_IMPL(M68K_JSR, translate_m68k_jmp_jsr), | |
547 RAW_IMPL(M68K_RTS, translate_m68k_rts), | |
548 RAW_IMPL(M68K_RTE, translate_m68k_rte), | |
549 RAW_IMPL(M68K_RTR, translate_m68k_rtr), | |
550 RAW_IMPL(M68K_LINK, translate_m68k_link), | |
551 RAW_IMPL(M68K_UNLK, translate_m68k_unlk), | |
552 | |
553 //SR/CCR stuff | |
554 RAW_IMPL(M68K_ANDI_CCR, translate_m68k_andi_ccr_sr), | |
555 RAW_IMPL(M68K_ANDI_SR, translate_m68k_andi_ccr_sr), | |
556 RAW_IMPL(M68K_EORI_CCR, translate_m68k_eori_ccr_sr), | |
557 RAW_IMPL(M68K_EORI_SR, translate_m68k_eori_ccr_sr), | |
558 RAW_IMPL(M68K_ORI_CCR, translate_m68k_ori_ccr_sr), | |
559 RAW_IMPL(M68K_ORI_SR, translate_m68k_ori_ccr_sr), | |
560 OP_IMPL(M68K_MOVE_CCR, translate_m68k_move_ccr_sr), | |
561 OP_IMPL(M68K_MOVE_SR, translate_m68k_move_ccr_sr), | |
562 OP_IMPL(M68K_MOVE_FROM_SR, translate_m68k_move_from_sr), | |
563 RAW_IMPL(M68K_STOP, translate_m68k_stop), | |
564 | |
565 //traps | |
566 OP_IMPL(M68K_CHK, translate_m68k_chk), | |
567 RAW_IMPL(M68K_TRAP, translate_m68k_trap), | |
568 RAW_IMPL(M68K_ILLEGAL, translate_m68k_illegal), | |
569 RAW_IMPL(M68K_INVALID, translate_m68k_invalid), | |
570 | |
571 //misc | |
572 RAW_IMPL(M68K_NOP, translate_m68k_nop), | |
573 RAW_IMPL(M68K_RESET, translate_m68k_reset), | |
574 | |
575 //currently unimplemented | |
576 //M68K_NBCD | |
577 //M68K_TAS | |
578 //M68K_TRAPV | |
579 }; | |
580 | |
581 void translate_m68k(m68k_options * opts, m68kinst * inst) | |
582 { | |
583 check_cycles_int(&opts->gen, inst->address); | |
584 impl_info * info = m68k_impls + inst->op; | |
585 if (info->itype == RAW_FUNC) { | |
586 info->impl.raw(opts, inst); | |
587 return; | |
588 } | |
589 | |
590 host_ea src_op, dst_op; | |
591 if (inst->src.addr_mode != MODE_UNUSED) { | |
592 translate_m68k_op(inst, &src_op, opts, 0); | |
593 } | |
594 if (inst->dst.addr_mode != MODE_UNUSED) { | |
595 translate_m68k_op(inst, &dst_op, opts, 1); | |
596 } | |
597 if (info->itype == OP_FUNC) { | |
598 info->impl.op(opts, inst, &src_op, &dst_op); | |
599 } else if (info->itype == BINARY_ARITH) { | |
600 translate_m68k_arith(opts, inst, info->impl.flag_mask, &src_op, &dst_op); | |
601 } else if (info->itype == UNARY_ARITH) { | |
602 translate_m68k_unary(opts, inst, info->impl.flag_mask, inst->dst.addr_mode != MODE_UNUSED ? &dst_op : &src_op); | |
603 } else { | |
604 m68k_disasm(inst, disasm_buf); | |
605 printf("%X: %s\ninstruction %d not yet implemented\n", inst->address, disasm_buf, inst->op); | |
606 exit(1); | |
435 } | 607 } |
436 } | 608 } |
437 | 609 |
438 void translate_m68k_stream(uint32_t address, m68k_context * context) | 610 void translate_m68k_stream(uint32_t address, m68k_context * context) |
439 { | 611 { |