Mercurial > repos > blastem
comparison m68k_core.c @ 744:fc68992cf18d
Merge windows branch with latest changes
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Thu, 28 May 2015 21:19:55 -0700 |
parents | 7367b14ac01c |
children | 724bbec47f86 41f73c76b978 |
comparison
equal
deleted
inserted
replaced
743:cf78cb045fa4 | 744:fc68992cf18d |
---|---|
84 call(&opts->gen.code, opts->write_32_highfirst); | 84 call(&opts->gen.code, opts->write_32_highfirst); |
85 break; | 85 break; |
86 } | 86 } |
87 } | 87 } |
88 | 88 |
89 void m68k_save_result(m68kinst * inst, m68k_options * opts) | |
90 { | |
91 code_info *code = &opts->gen.code; | |
92 if (inst->dst.addr_mode != MODE_REG && inst->dst.addr_mode != MODE_AREG && inst->dst.addr_mode != MODE_UNUSED) { | |
93 if (inst->dst.addr_mode == MODE_AREG_PREDEC && inst->src.addr_mode == MODE_AREG_PREDEC && inst->op != M68K_MOVE) { | |
94 areg_to_native(opts, inst->dst.params.regs.pri, opts->gen.scratch2); | |
95 } | |
96 switch (inst->extra.size) | |
97 { | |
98 case OPSIZE_BYTE: | |
99 call(code, opts->write_8); | |
100 break; | |
101 case OPSIZE_WORD: | |
102 call(code, opts->write_16); | |
103 break; | |
104 case OPSIZE_LONG: | |
105 call(code, opts->write_32_lowfirst); | |
106 break; | |
107 } | |
108 } | |
109 } | |
110 | |
89 void translate_m68k_lea_pea(m68k_options * opts, m68kinst * inst) | 111 void translate_m68k_lea_pea(m68k_options * opts, m68kinst * inst) |
90 { | 112 { |
91 code_info *code = &opts->gen.code; | 113 code_info *code = &opts->gen.code; |
92 int8_t dst_reg = inst->op == M68K_PEA ? opts->gen.scratch1 : native_reg(&(inst->dst), opts); | 114 int8_t dst_reg = inst->op == M68K_PEA ? opts->gen.scratch1 : native_reg(&(inst->dst), opts); |
93 switch(inst->src.addr_mode) | 115 switch(inst->src.addr_mode) |
171 } | 193 } |
172 | 194 |
173 void jump_m68k_abs(m68k_options * opts, uint32_t address) | 195 void jump_m68k_abs(m68k_options * opts, uint32_t address) |
174 { | 196 { |
175 code_info *code = &opts->gen.code; | 197 code_info *code = &opts->gen.code; |
176 code_ptr dest_addr = get_native_address(opts->gen.native_code_map, address); | 198 code_ptr dest_addr = get_native_address(opts, address); |
177 if (!dest_addr) { | 199 if (!dest_addr) { |
178 opts->gen.deferred = defer_address(opts->gen.deferred, address, code->cur + 1); | 200 opts->gen.deferred = defer_address(opts->gen.deferred, address, code->cur + 1); |
179 //dummy address to be replaced later, make sure it generates a 4-byte displacement | 201 //dummy address to be replaced later, make sure it generates a 4-byte displacement |
180 dest_addr = code->cur + 256; | 202 dest_addr = code->cur + 256; |
181 } | 203 } |
501 areg_to_native(opts, 7, opts->gen.scratch2); | 523 areg_to_native(opts, 7, opts->gen.scratch2); |
502 areg_to_native(opts, 8, opts->aregs[7]); | 524 areg_to_native(opts, 8, opts->aregs[7]); |
503 native_to_areg(opts, opts->gen.scratch2, 8); | 525 native_to_areg(opts, opts->gen.scratch2, 8); |
504 } | 526 } |
505 | 527 |
506 code_ptr get_native_address(native_map_slot * native_code_map, uint32_t address) | 528 void translate_m68k_reset(m68k_options *opts, m68kinst *inst) |
507 { | 529 { |
508 address &= 0xFFFFFF; | 530 code_info *code = &opts->gen.code; |
531 call(code, opts->gen.save_context); | |
532 call_args(code, (code_ptr)print_regs_exit, 1, opts->gen.context_reg); | |
533 } | |
534 | |
535 void translate_m68k_rte(m68k_options *opts, m68kinst *inst) | |
536 { | |
537 code_info *code = &opts->gen.code; | |
538 //TODO: Trap if not in system mode | |
539 //Read saved SR | |
540 areg_to_native(opts, 7, opts->gen.scratch1); | |
541 call(code, opts->read_16); | |
542 addi_areg(opts, 2, 7); | |
543 call(code, opts->set_sr); | |
544 //Read saved PC | |
545 areg_to_native(opts, 7, opts->gen.scratch1); | |
546 call(code, opts->read_32); | |
547 addi_areg(opts, 4, 7); | |
548 check_user_mode_swap_ssp_usp(opts); | |
549 //Get native address, sync components, recalculate integer points and jump to returned address | |
550 call(code, opts->native_addr_and_sync); | |
551 jmp_r(code, opts->gen.scratch1); | |
552 } | |
553 | |
554 code_ptr get_native_address(m68k_options *opts, uint32_t address) | |
555 { | |
556 native_map_slot * native_code_map = opts->gen.native_code_map; | |
557 address &= opts->gen.address_mask; | |
558 if (address & 1) { | |
559 return opts->odd_address; | |
560 } | |
509 address /= 2; | 561 address /= 2; |
510 uint32_t chunk = address / NATIVE_CHUNK_SIZE; | 562 uint32_t chunk = address / NATIVE_CHUNK_SIZE; |
511 if (!native_code_map[chunk].base) { | 563 if (!native_code_map[chunk].base) { |
512 return NULL; | 564 return NULL; |
513 } | 565 } |
518 return native_code_map[chunk].base + native_code_map[chunk].offsets[offset]; | 570 return native_code_map[chunk].base + native_code_map[chunk].offsets[offset]; |
519 } | 571 } |
520 | 572 |
521 code_ptr get_native_from_context(m68k_context * context, uint32_t address) | 573 code_ptr get_native_from_context(m68k_context * context, uint32_t address) |
522 { | 574 { |
523 return get_native_address(context->native_code_map, address); | 575 return get_native_address(context->options, address); |
524 } | 576 } |
525 | 577 |
526 uint32_t get_instruction_start(native_map_slot * native_code_map, uint32_t address) | 578 uint32_t get_instruction_start(native_map_slot * native_code_map, uint32_t address) |
527 { | 579 { |
580 //FIXME: Use opts->gen.address_mask | |
528 address &= 0xFFFFFF; | 581 address &= 0xFFFFFF; |
529 address /= 2; | 582 address /= 2; |
530 uint32_t chunk = address / NATIVE_CHUNK_SIZE; | 583 uint32_t chunk = address / NATIVE_CHUNK_SIZE; |
531 if (!native_code_map[chunk].base) { | 584 if (!native_code_map[chunk].base) { |
532 return 0; | 585 return 0; |
545 | 598 |
546 void map_native_address(m68k_context * context, uint32_t address, code_ptr native_addr, uint8_t size, uint8_t native_size) | 599 void map_native_address(m68k_context * context, uint32_t address, code_ptr native_addr, uint8_t size, uint8_t native_size) |
547 { | 600 { |
548 native_map_slot * native_code_map = context->native_code_map; | 601 native_map_slot * native_code_map = context->native_code_map; |
549 m68k_options * opts = context->options; | 602 m68k_options * opts = context->options; |
550 address &= 0xFFFFFF; | 603 address &= opts->gen.address_mask; |
551 if (address > 0xE00000) { | 604 uint32_t meta_off = 0; |
552 context->ram_code_flags[(address & 0xC000) >> 14] |= 1 << ((address & 0x3800) >> 11); | 605 //TODO: Refactor part of this loop into some kind of get_ram_chunk function |
553 if (((address & 0x3FFF) + size) & 0xC000) { | 606 for (int i = 0; i < opts->gen.memmap_chunks; i++) { |
554 context->ram_code_flags[((address+size) & 0xC000) >> 14] |= 1 << (((address+size) & 0x3800) >> 11); | 607 if (address >= opts->gen.memmap[i].start && address < opts->gen.memmap[i].end) { |
555 } | 608 if ((opts->gen.memmap[i].flags & (MMAP_WRITE | MMAP_CODE)) == (MMAP_WRITE | MMAP_CODE)) { |
556 uint32_t slot = (address & 0xFFFF)/1024; | 609 uint32_t masked = (address & opts->gen.memmap[i].mask); |
557 if (!opts->gen.ram_inst_sizes[slot]) { | 610 uint32_t final_off = masked + meta_off; |
558 opts->gen.ram_inst_sizes[slot] = malloc(sizeof(uint8_t) * 512); | 611 uint32_t ram_flags_off = final_off >> (opts->gen.ram_flags_shift + 3); |
559 } | 612 context->ram_code_flags[ram_flags_off] |= 1 << ((final_off >> opts->gen.ram_flags_shift) & 7); |
560 opts->gen.ram_inst_sizes[slot][((address & 0xFFFF)/2)%512] = native_size; | 613 |
614 uint32_t slot = final_off / 1024; | |
615 if (!opts->gen.ram_inst_sizes[slot]) { | |
616 opts->gen.ram_inst_sizes[slot] = malloc(sizeof(uint8_t) * 512); | |
617 } | |
618 opts->gen.ram_inst_sizes[slot][(final_off/2) & 511] = native_size; | |
619 | |
620 //TODO: Deal with case in which end of instruction is in a different memory chunk | |
621 masked = (address + size - 1) & opts->gen.memmap[i].mask; | |
622 final_off = masked + meta_off; | |
623 ram_flags_off = final_off >> (opts->gen.ram_flags_shift + 3); | |
624 context->ram_code_flags[ram_flags_off] |= 1 << ((final_off >> opts->gen.ram_flags_shift) & 7); | |
625 } | |
626 break; | |
627 } else if ((opts->gen.memmap[i].flags & (MMAP_WRITE | MMAP_CODE)) == (MMAP_WRITE | MMAP_CODE)) { | |
628 uint32_t size = chunk_size(&opts->gen, opts->gen.memmap + i); | |
629 meta_off += size; | |
630 } | |
561 } | 631 } |
562 address/= 2; | 632 address/= 2; |
563 uint32_t chunk = address / NATIVE_CHUNK_SIZE; | 633 uint32_t chunk = address / NATIVE_CHUNK_SIZE; |
564 if (!native_code_map[chunk].base) { | 634 if (!native_code_map[chunk].base) { |
565 native_code_map[chunk].base = native_addr; | 635 native_code_map[chunk].base = native_addr; |
567 memset(native_code_map[chunk].offsets, 0xFF, sizeof(int32_t) * NATIVE_CHUNK_SIZE); | 637 memset(native_code_map[chunk].offsets, 0xFF, sizeof(int32_t) * NATIVE_CHUNK_SIZE); |
568 } | 638 } |
569 uint32_t offset = address % NATIVE_CHUNK_SIZE; | 639 uint32_t offset = address % NATIVE_CHUNK_SIZE; |
570 native_code_map[chunk].offsets[offset] = native_addr-native_code_map[chunk].base; | 640 native_code_map[chunk].offsets[offset] = native_addr-native_code_map[chunk].base; |
571 for(address++,size-=2; size; address++,size-=2) { | 641 for(address++,size-=2; size; address++,size-=2) { |
642 address &= opts->gen.address_mask >> 1; | |
572 chunk = address / NATIVE_CHUNK_SIZE; | 643 chunk = address / NATIVE_CHUNK_SIZE; |
573 offset = address % NATIVE_CHUNK_SIZE; | 644 offset = address % NATIVE_CHUNK_SIZE; |
574 if (!native_code_map[chunk].base) { | 645 if (!native_code_map[chunk].base) { |
575 native_code_map[chunk].base = native_addr; | 646 native_code_map[chunk].base = native_addr; |
576 native_code_map[chunk].offsets = malloc(sizeof(int32_t) * NATIVE_CHUNK_SIZE); | 647 native_code_map[chunk].offsets = malloc(sizeof(int32_t) * NATIVE_CHUNK_SIZE); |
577 memset(native_code_map[chunk].offsets, 0xFF, sizeof(int32_t) * NATIVE_CHUNK_SIZE); | 648 memset(native_code_map[chunk].offsets, 0xFF, sizeof(int32_t) * NATIVE_CHUNK_SIZE); |
578 } | 649 } |
579 native_code_map[chunk].offsets[offset] = EXTENSION_WORD; | 650 if (native_code_map[chunk].offsets[offset] == INVALID_OFFSET) { |
651 //TODO: Better handling of overlapping instructions | |
652 native_code_map[chunk].offsets[offset] = EXTENSION_WORD; | |
653 } | |
580 } | 654 } |
581 } | 655 } |
582 | 656 |
583 uint8_t get_native_inst_size(m68k_options * opts, uint32_t address) | 657 uint8_t get_native_inst_size(m68k_options * opts, uint32_t address) |
584 { | 658 { |
585 if (address < 0xE00000) { | 659 address &= opts->gen.address_mask; |
586 return 0; | 660 uint32_t meta_off = 0; |
587 } | 661 for (int i = 0; i < opts->gen.memmap_chunks; i++) { |
588 uint32_t slot = (address & 0xFFFF)/1024; | 662 if (address >= opts->gen.memmap[i].start && address < opts->gen.memmap[i].end) { |
589 return opts->gen.ram_inst_sizes[slot][((address & 0xFFFF)/2)%512]; | 663 if ((opts->gen.memmap[i].flags & (MMAP_WRITE | MMAP_CODE)) != (MMAP_WRITE | MMAP_CODE)) { |
664 return 0; | |
665 } | |
666 meta_off += address & opts->gen.memmap[i].mask; | |
667 break; | |
668 } else if ((opts->gen.memmap[i].flags & (MMAP_WRITE | MMAP_CODE)) == (MMAP_WRITE | MMAP_CODE)) { | |
669 uint32_t size = chunk_size(&opts->gen, opts->gen.memmap + i); | |
670 meta_off += size; | |
671 } | |
672 } | |
673 uint32_t slot = meta_off/1024; | |
674 return opts->gen.ram_inst_sizes[slot][(meta_off/2)%512]; | |
590 } | 675 } |
591 | 676 |
592 uint8_t m68k_is_terminal(m68kinst * inst) | 677 uint8_t m68k_is_terminal(m68kinst * inst) |
593 { | 678 { |
594 return inst->op == M68K_RTS || inst->op == M68K_RTE || inst->op == M68K_RTR || inst->op == M68K_JMP | 679 return inst->op == M68K_RTS || inst->op == M68K_RTE || inst->op == M68K_RTR || inst->op == M68K_JMP |
647 OP_IMPL(M68K_MULS, translate_m68k_mul), | 732 OP_IMPL(M68K_MULS, translate_m68k_mul), |
648 OP_IMPL(M68K_MULU, translate_m68k_mul), | 733 OP_IMPL(M68K_MULU, translate_m68k_mul), |
649 RAW_IMPL(M68K_EXT, translate_m68k_ext), | 734 RAW_IMPL(M68K_EXT, translate_m68k_ext), |
650 UNARY_IMPL(M68K_NEG, X|N|Z|V|C), | 735 UNARY_IMPL(M68K_NEG, X|N|Z|V|C), |
651 OP_IMPL(M68K_NEGX, translate_m68k_negx), | 736 OP_IMPL(M68K_NEGX, translate_m68k_negx), |
652 UNARY_IMPL(M68K_NOT, X|N|Z|V|C), | 737 UNARY_IMPL(M68K_NOT, N|Z|V|C), |
653 UNARY_IMPL(M68K_TST, N|Z|V0|C0), | 738 UNARY_IMPL(M68K_TST, N|Z|V0|C0), |
654 | 739 |
655 //shift/rotate | 740 //shift/rotate |
656 OP_IMPL(M68K_ASL, translate_m68k_sl), | 741 OP_IMPL(M68K_ASL, translate_m68k_sl), |
657 OP_IMPL(M68K_LSL, translate_m68k_sl), | 742 OP_IMPL(M68K_LSL, translate_m68k_sl), |
721 }; | 806 }; |
722 | 807 |
723 void translate_m68k(m68k_options * opts, m68kinst * inst) | 808 void translate_m68k(m68k_options * opts, m68kinst * inst) |
724 { | 809 { |
725 check_cycles_int(&opts->gen, inst->address); | 810 check_cycles_int(&opts->gen, inst->address); |
811 //log_address(&opts->gen, inst->address, "M68K: %X @ %d\n"); | |
726 impl_info * info = m68k_impls + inst->op; | 812 impl_info * info = m68k_impls + inst->op; |
727 if (info->itype == RAW_FUNC) { | 813 if (info->itype == RAW_FUNC) { |
728 info->impl.raw(opts, inst); | 814 info->impl.raw(opts, inst); |
729 return; | 815 return; |
730 } | 816 } |
752 void translate_m68k_stream(uint32_t address, m68k_context * context) | 838 void translate_m68k_stream(uint32_t address, m68k_context * context) |
753 { | 839 { |
754 m68kinst instbuf; | 840 m68kinst instbuf; |
755 m68k_options * opts = context->options; | 841 m68k_options * opts = context->options; |
756 code_info *code = &opts->gen.code; | 842 code_info *code = &opts->gen.code; |
757 address &= 0xFFFFFF; | 843 if(get_native_address(opts, address)) { |
758 if(get_native_address(opts->gen.native_code_map, address)) { | |
759 return; | 844 return; |
760 } | 845 } |
761 char disbuf[1024]; | |
762 uint16_t *encoded, *next; | 846 uint16_t *encoded, *next; |
763 if ((address & 0xFFFFFF) < 0x400000) { | |
764 encoded = context->mem_pointers[0] + (address & 0xFFFFFF)/2; | |
765 } else if ((address & 0xFFFFFF) > 0xE00000) { | |
766 encoded = context->mem_pointers[1] + (address & 0xFFFF)/2; | |
767 } else { | |
768 printf("attempt to translate non-memory address: %X\n", address); | |
769 exit(1); | |
770 } | |
771 do { | 847 do { |
772 if (opts->address_log) { | 848 if (opts->address_log) { |
773 fprintf(opts->address_log, "%X\n", address); | 849 fprintf(opts->address_log, "%X\n", address); |
850 fflush(opts->address_log); | |
774 } | 851 } |
775 do { | 852 do { |
776 if (address >= 0x400000 && address < 0xE00000) { | 853 if (address & 1) { |
854 break; | |
855 } | |
856 encoded = get_native_pointer(address, (void **)context->mem_pointers, &opts->gen); | |
857 if (!encoded) { | |
858 map_native_address(context, address, code->cur, 2, 1); | |
777 translate_out_of_bounds(code); | 859 translate_out_of_bounds(code); |
778 break; | 860 break; |
779 } | 861 } |
780 code_ptr existing = get_native_address(opts->gen.native_code_map, address); | 862 code_ptr existing = get_native_address(opts, address); |
781 if (existing) { | 863 if (existing) { |
782 jmp(code, existing); | 864 jmp(code, existing); |
783 break; | 865 break; |
784 } | 866 } |
785 next = m68k_decode(encoded, &instbuf, address); | 867 next = m68k_decode(encoded, &instbuf, address); |
786 if (instbuf.op == M68K_INVALID) { | 868 if (instbuf.op == M68K_INVALID) { |
787 instbuf.src.params.immed = *encoded; | 869 instbuf.src.params.immed = *encoded; |
788 } | 870 } |
789 uint16_t m68k_size = (next-encoded)*2; | 871 uint16_t m68k_size = (next-encoded)*2; |
790 address += m68k_size; | 872 address += m68k_size; |
791 encoded = next; | 873 //char disbuf[1024]; |
792 //m68k_disasm(&instbuf, disbuf); | 874 //m68k_disasm(&instbuf, disbuf); |
793 //printf("%X: %s\n", instbuf.address, disbuf); | 875 //printf("%X: %s\n", instbuf.address, disbuf); |
794 | 876 |
795 //make sure the beginning of the code for an instruction is contiguous | 877 //make sure the beginning of the code for an instruction is contiguous |
796 check_code_prologue(code); | 878 check_code_prologue(code); |
800 map_native_address(context, instbuf.address, start, m68k_size, after-start); | 882 map_native_address(context, instbuf.address, start, m68k_size, after-start); |
801 } while(!m68k_is_terminal(&instbuf)); | 883 } while(!m68k_is_terminal(&instbuf)); |
802 process_deferred(&opts->gen.deferred, context, (native_addr_func)get_native_from_context); | 884 process_deferred(&opts->gen.deferred, context, (native_addr_func)get_native_from_context); |
803 if (opts->gen.deferred) { | 885 if (opts->gen.deferred) { |
804 address = opts->gen.deferred->address; | 886 address = opts->gen.deferred->address; |
805 if ((address & 0xFFFFFF) < 0x400000) { | 887 } |
806 encoded = context->mem_pointers[0] + (address & 0xFFFFFF)/2; | 888 } while(opts->gen.deferred); |
807 } else if ((address & 0xFFFFFF) > 0xE00000) { | |
808 encoded = context->mem_pointers[1] + (address & 0xFFFF)/2; | |
809 } else { | |
810 printf("attempt to translate non-memory address: %X\n", address); | |
811 exit(1); | |
812 } | |
813 } else { | |
814 encoded = NULL; | |
815 } | |
816 } while(encoded != NULL); | |
817 } | 889 } |
818 | 890 |
819 void * m68k_retranslate_inst(uint32_t address, m68k_context * context) | 891 void * m68k_retranslate_inst(uint32_t address, m68k_context * context) |
820 { | 892 { |
821 m68k_options * opts = context->options; | 893 m68k_options * opts = context->options; |
822 code_info *code = &opts->gen.code; | 894 code_info *code = &opts->gen.code; |
823 uint8_t orig_size = get_native_inst_size(opts, address); | 895 uint8_t orig_size = get_native_inst_size(opts, address); |
824 code_ptr orig_start = get_native_address(context->native_code_map, address); | 896 code_ptr orig_start = get_native_address(context->options, address); |
825 uint32_t orig = address; | 897 uint32_t orig = address; |
826 code_info orig_code; | 898 code_info orig_code; |
827 orig_code.cur = orig_start; | 899 orig_code.cur = orig_start; |
828 orig_code.last = orig_start + orig_size + 5; | 900 orig_code.last = orig_start + orig_size + 5; |
829 address &= 0xFFFF; | 901 uint16_t *after, *inst = get_native_pointer(address, (void **)context->mem_pointers, &opts->gen); |
830 uint16_t *after, *inst = context->mem_pointers[1] + address/2; | |
831 m68kinst instbuf; | 902 m68kinst instbuf; |
832 after = m68k_decode(inst, &instbuf, orig); | 903 after = m68k_decode(inst, &instbuf, orig); |
833 if (orig_size != MAX_NATIVE_SIZE) { | 904 if (orig_size != MAX_NATIVE_SIZE) { |
834 deferred_addr * orig_deferred = opts->gen.deferred; | 905 deferred_addr * orig_deferred = opts->gen.deferred; |
835 | 906 |
836 //make sure the beginning of the code for an instruction is contiguous | 907 //make sure we have enough code space for the max size instruction |
837 check_code_prologue(code); | 908 check_alloc_code(code, MAX_NATIVE_SIZE); |
838 code_ptr native_start = code->cur; | 909 code_ptr native_start = code->cur; |
839 translate_m68k(opts, &instbuf); | 910 translate_m68k(opts, &instbuf); |
840 code_ptr native_end = code->cur; | 911 code_ptr native_end = code->cur; |
841 uint8_t is_terminal = m68k_is_terminal(&instbuf); | 912 /*uint8_t is_terminal = m68k_is_terminal(&instbuf); |
842 if ((native_end - native_start) <= orig_size) { | 913 if ((native_end - native_start) <= orig_size) { |
843 code_ptr native_next; | 914 code_ptr native_next; |
844 if (!is_terminal) { | 915 if (!is_terminal) { |
845 native_next = get_native_address(context->native_code_map, orig + (after-inst)*2); | 916 native_next = get_native_address(context->native_code_map, orig + (after-inst)*2); |
846 } | 917 } |
847 if (is_terminal || (native_next && ((native_next == orig_start + orig_size) || (orig_size - (native_end - native_start)) > 5))) { | 918 if (is_terminal || (native_next && ((native_next == orig_start + orig_size) || (orig_size - (native_end - native_start)) > 5))) { |
919 printf("Using original location: %p\n", orig_code.cur); | |
848 remove_deferred_until(&opts->gen.deferred, orig_deferred); | 920 remove_deferred_until(&opts->gen.deferred, orig_deferred); |
849 code_info tmp; | 921 code_info tmp; |
850 tmp.cur = code->cur; | 922 tmp.cur = code->cur; |
851 tmp.last = code->last; | 923 tmp.last = code->last; |
852 code->cur = orig_code.cur; | 924 code->cur = orig_code.cur; |
859 nop_fill_or_jmp_next(&orig_code, orig_start + orig_size, native_next); | 931 nop_fill_or_jmp_next(&orig_code, orig_start + orig_size, native_next); |
860 } | 932 } |
861 m68k_handle_deferred(context); | 933 m68k_handle_deferred(context); |
862 return orig_start; | 934 return orig_start; |
863 } | 935 } |
864 } | 936 }*/ |
865 | 937 |
866 map_native_address(context, instbuf.address, native_start, (after-inst)*2, MAX_NATIVE_SIZE); | 938 map_native_address(context, instbuf.address, native_start, (after-inst)*2, MAX_NATIVE_SIZE); |
867 | 939 |
868 jmp(&orig_code, native_start); | 940 jmp(&orig_code, native_start); |
869 if (!m68k_is_terminal(&instbuf)) { | 941 if (!m68k_is_terminal(&instbuf)) { |
878 code->cur = native_start + MAX_NATIVE_SIZE; | 950 code->cur = native_start + MAX_NATIVE_SIZE; |
879 } | 951 } |
880 m68k_handle_deferred(context); | 952 m68k_handle_deferred(context); |
881 return native_start; | 953 return native_start; |
882 } else { | 954 } else { |
883 code_info tmp; | 955 code_info tmp = *code; |
884 tmp.cur = code->cur; | 956 *code = orig_code; |
885 tmp.last = code->last; | |
886 code->cur = orig_code.cur; | |
887 code->last = orig_code.last; | |
888 translate_m68k(opts, &instbuf); | 957 translate_m68k(opts, &instbuf); |
958 orig_code = *code; | |
959 *code = tmp; | |
889 if (!m68k_is_terminal(&instbuf)) { | 960 if (!m68k_is_terminal(&instbuf)) { |
890 jmp(code, get_native_address_trans(context, orig + (after-inst)*2)); | 961 jmp(&orig_code, get_native_address_trans(context, orig + (after-inst)*2)); |
891 } | 962 } |
892 code->cur = tmp.cur; | |
893 code->last = tmp.last; | |
894 m68k_handle_deferred(context); | 963 m68k_handle_deferred(context); |
895 return orig_start; | 964 return orig_start; |
896 } | 965 } |
897 } | 966 } |
898 | 967 |
899 code_ptr get_native_address_trans(m68k_context * context, uint32_t address) | 968 code_ptr get_native_address_trans(m68k_context * context, uint32_t address) |
900 { | 969 { |
901 address &= 0xFFFFFF; | 970 code_ptr ret = get_native_address(context->options, address); |
902 code_ptr ret = get_native_address(context->native_code_map, address); | |
903 if (!ret) { | 971 if (!ret) { |
904 translate_m68k_stream(address, context); | 972 translate_m68k_stream(address, context); |
905 ret = get_native_address(context->native_code_map, address); | 973 ret = get_native_address(context->options, address); |
906 } | 974 } |
907 return ret; | 975 return ret; |
908 } | 976 } |
909 | 977 |
910 void remove_breakpoint(m68k_context * context, uint32_t address) | 978 void remove_breakpoint(m68k_context * context, uint32_t address) |
911 { | 979 { |
912 code_ptr native = get_native_address(context->native_code_map, address); | 980 code_ptr native = get_native_address(context->options, address); |
913 check_cycles_int(context->options, address); | 981 code_info tmp = context->options->gen.code; |
982 context->options->gen.code.cur = native; | |
983 context->options->gen.code.last = native + MAX_NATIVE_SIZE; | |
984 check_cycles_int(&context->options->gen, address); | |
985 context->options->gen.code = tmp; | |
914 } | 986 } |
915 | 987 |
916 void start_68k_context(m68k_context * context, uint32_t address) | 988 void start_68k_context(m68k_context * context, uint32_t address) |
917 { | 989 { |
918 code_ptr addr = get_native_address_trans(context, address); | 990 code_ptr addr = get_native_address_trans(context, address); |
920 options->start_context(addr, context); | 992 options->start_context(addr, context); |
921 } | 993 } |
922 | 994 |
923 void m68k_reset(m68k_context * context) | 995 void m68k_reset(m68k_context * context) |
924 { | 996 { |
925 //TODO: Make this actually use the normal read functions | 997 //TODO: Actually execute the M68K reset vector rather than simulating some of its behavior |
926 context->aregs[7] = context->mem_pointers[0][0] << 16 | context->mem_pointers[0][1]; | 998 uint16_t *reset_vec = get_native_pointer(0, (void **)context->mem_pointers, &context->options->gen); |
927 uint32_t address = context->mem_pointers[0][2] << 16 | context->mem_pointers[0][3]; | 999 context->aregs[7] = reset_vec[0] << 16 | reset_vec[1]; |
1000 uint32_t address = reset_vec[2] << 16 | reset_vec[3]; | |
928 start_68k_context(context, address); | 1001 start_68k_context(context, address); |
929 } | 1002 } |
930 | 1003 |
931 | 1004 |
932 void init_68k_context(m68k_context * context, native_map_slot * native_code_map, void * opts) | 1005 m68k_context * init_68k_context(m68k_options * opts) |
933 { | 1006 { |
1007 m68k_context * context = malloc(sizeof(m68k_context) + ram_size(&opts->gen) / (1 << opts->gen.ram_flags_shift) / 8); | |
934 memset(context, 0, sizeof(m68k_context)); | 1008 memset(context, 0, sizeof(m68k_context)); |
935 context->native_code_map = native_code_map; | 1009 context->native_code_map = opts->gen.native_code_map; |
936 context->options = opts; | 1010 context->options = opts; |
937 context->int_cycle = 0xFFFFFFFF; | 1011 context->int_cycle = CYCLE_NEVER; |
938 context->status = 0x27; | 1012 context->status = 0x27; |
939 } | 1013 return context; |
1014 } |