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 }