comparison m68k_core.c @ 690:fc04781f4d28

Removed hardcoded assumptions in M68K core about which parts of the memory map are RAM
author Michael Pavone <pavone@retrodev.com>
date Wed, 14 Jan 2015 09:38:54 -0800
parents 8c546bc1d773
children e11e68918691
comparison
equal deleted inserted replaced
689:858e31f977ae 690:fc04781f4d28
551 jmp_r(code, opts->gen.scratch1); 551 jmp_r(code, opts->gen.scratch1);
552 } 552 }
553 553
554 code_ptr get_native_address(native_map_slot * native_code_map, uint32_t address) 554 code_ptr get_native_address(native_map_slot * native_code_map, uint32_t address)
555 { 555 {
556 //FIXME: Use opts->gen.address_mask
556 address &= 0xFFFFFF; 557 address &= 0xFFFFFF;
557 address /= 2; 558 address /= 2;
558 uint32_t chunk = address / NATIVE_CHUNK_SIZE; 559 uint32_t chunk = address / NATIVE_CHUNK_SIZE;
559 if (!native_code_map[chunk].base) { 560 if (!native_code_map[chunk].base) {
560 return NULL; 561 return NULL;
571 return get_native_address(context->native_code_map, address); 572 return get_native_address(context->native_code_map, address);
572 } 573 }
573 574
574 uint32_t get_instruction_start(native_map_slot * native_code_map, uint32_t address) 575 uint32_t get_instruction_start(native_map_slot * native_code_map, uint32_t address)
575 { 576 {
577 //FIXME: Use opts->gen.address_mask
576 address &= 0xFFFFFF; 578 address &= 0xFFFFFF;
577 address /= 2; 579 address /= 2;
578 uint32_t chunk = address / NATIVE_CHUNK_SIZE; 580 uint32_t chunk = address / NATIVE_CHUNK_SIZE;
579 if (!native_code_map[chunk].base) { 581 if (!native_code_map[chunk].base) {
580 return 0; 582 return 0;
593 595
594 void map_native_address(m68k_context * context, uint32_t address, code_ptr native_addr, uint8_t size, uint8_t native_size) 596 void map_native_address(m68k_context * context, uint32_t address, code_ptr native_addr, uint8_t size, uint8_t native_size)
595 { 597 {
596 native_map_slot * native_code_map = context->native_code_map; 598 native_map_slot * native_code_map = context->native_code_map;
597 m68k_options * opts = context->options; 599 m68k_options * opts = context->options;
598 address &= 0xFFFFFF; 600 address &= opts->gen.address_mask;
599 if (address > 0xE00000) { 601 uint32_t meta_off = 0;
600 context->ram_code_flags[(address & 0xC000) >> 14] |= 1 << ((address & 0x3800) >> 11); 602 //TODO: Refactor part of this loop into some kind of get_ram_chunk function
601 if (((address & 0x3FFF) + size) & 0xC000) { 603 for (int i = 0; i < opts->gen.memmap_chunks; i++) {
602 context->ram_code_flags[((address+size) & 0xC000) >> 14] |= 1 << (((address+size) & 0x3800) >> 11); 604 if (address >= opts->gen.memmap[i].start && address < opts->gen.memmap[i].end) {
603 } 605 if ((opts->gen.memmap[i].flags & (MMAP_WRITE | MMAP_CODE)) == (MMAP_WRITE | MMAP_CODE)) {
604 uint32_t slot = (address & 0xFFFF)/1024; 606 uint32_t masked = (address & opts->gen.memmap[i].mask);
605 if (!opts->gen.ram_inst_sizes[slot]) { 607 uint32_t final_off = masked + meta_off;
606 opts->gen.ram_inst_sizes[slot] = malloc(sizeof(uint8_t) * 512); 608 uint32_t ram_flags_off = final_off >> (opts->gen.ram_flags_shift + 3);
607 } 609 context->ram_code_flags[ram_flags_off] |= 1 << ((final_off >> opts->gen.ram_flags_shift) & 3);
608 opts->gen.ram_inst_sizes[slot][((address & 0xFFFF)/2)%512] = native_size; 610
611 uint32_t slot = final_off / 1024;
612 if (!opts->gen.ram_inst_sizes[slot]) {
613 opts->gen.ram_inst_sizes[slot] = malloc(sizeof(uint8_t) * 512);
614 }
615 opts->gen.ram_inst_sizes[slot][(final_off/2) & 511] = native_size;
616
617 //TODO: Deal with case in which end of instruction is in a different memory chunk
618 masked = (address + size - 1) & opts->gen.memmap[i].mask;
619 final_off = masked + meta_off;
620 ram_flags_off = final_off >> (opts->gen.ram_flags_shift + 3);
621 context->ram_code_flags[ram_flags_off] |= 1 << ((final_off >> opts->gen.ram_flags_shift) & 3);
622 }
623 break;
624 } else if ((opts->gen.memmap[i].flags & (MMAP_WRITE | MMAP_CODE)) == (MMAP_WRITE | MMAP_CODE)) {
625 uint32_t size = chunk_size(&opts->gen, opts->gen.memmap + i);
626 meta_off += size;
627 }
609 } 628 }
610 address/= 2; 629 address/= 2;
611 uint32_t chunk = address / NATIVE_CHUNK_SIZE; 630 uint32_t chunk = address / NATIVE_CHUNK_SIZE;
612 if (!native_code_map[chunk].base) { 631 if (!native_code_map[chunk].base) {
613 native_code_map[chunk].base = native_addr; 632 native_code_map[chunk].base = native_addr;
628 } 647 }
629 } 648 }
630 649
631 uint8_t get_native_inst_size(m68k_options * opts, uint32_t address) 650 uint8_t get_native_inst_size(m68k_options * opts, uint32_t address)
632 { 651 {
633 if (address < 0xE00000) { 652 address &= opts->gen.address_mask;
634 return 0; 653 uint32_t meta_off = 0;
635 } 654 for (int i = 0; i < opts->gen.memmap_chunks; i++) {
636 uint32_t slot = (address & 0xFFFF)/1024; 655 if (address >= opts->gen.memmap[i].start && address < opts->gen.memmap[i].end) {
637 return opts->gen.ram_inst_sizes[slot][((address & 0xFFFF)/2)%512]; 656 if ((opts->gen.memmap[i].flags & (MMAP_WRITE | MMAP_CODE)) != (MMAP_WRITE | MMAP_CODE)) {
657 return 0;
658 }
659 meta_off += address & opts->gen.memmap[i].mask;
660 break;
661 } else if ((opts->gen.memmap[i].flags & (MMAP_WRITE | MMAP_CODE)) == (MMAP_WRITE | MMAP_CODE)) {
662 uint32_t size = chunk_size(&opts->gen, opts->gen.memmap + i);
663 meta_off += size;
664 }
665 }
666 uint32_t slot = meta_off/1024;
667 return opts->gen.ram_inst_sizes[slot][(meta_off/2)%512];
638 } 668 }
639 669
640 uint8_t m68k_is_terminal(m68kinst * inst) 670 uint8_t m68k_is_terminal(m68kinst * inst)
641 { 671 {
642 return inst->op == M68K_RTS || inst->op == M68K_RTE || inst->op == M68K_RTR || inst->op == M68K_JMP 672 return inst->op == M68K_RTS || inst->op == M68K_RTE || inst->op == M68K_RTR || inst->op == M68K_JMP
924 } 954 }
925 } 955 }
926 956
927 code_ptr get_native_address_trans(m68k_context * context, uint32_t address) 957 code_ptr get_native_address_trans(m68k_context * context, uint32_t address)
928 { 958 {
959 //FIXME: Use opts->gen.address_mask
929 address &= 0xFFFFFF; 960 address &= 0xFFFFFF;
930 code_ptr ret = get_native_address(context->native_code_map, address); 961 code_ptr ret = get_native_address(context->native_code_map, address);
931 if (!ret) { 962 if (!ret) {
932 translate_m68k_stream(address, context); 963 translate_m68k_stream(address, context);
933 ret = get_native_address(context->native_code_map, address); 964 ret = get_native_address(context->native_code_map, address);
960 uint32_t address = reset_vec[2] << 16 | reset_vec[3]; 991 uint32_t address = reset_vec[2] << 16 | reset_vec[3];
961 start_68k_context(context, address); 992 start_68k_context(context, address);
962 } 993 }
963 994
964 995
965 void init_68k_context(m68k_context * context, native_map_slot * native_code_map, void * opts) 996 m68k_context * init_68k_context(m68k_options * opts)
966 { 997 {
998 m68k_context * context = malloc(sizeof(m68k_context) + ram_size(&opts->gen) / (1 << opts->gen.ram_flags_shift) / 8);
967 memset(context, 0, sizeof(m68k_context)); 999 memset(context, 0, sizeof(m68k_context));
968 context->native_code_map = native_code_map; 1000 context->native_code_map = opts->gen.native_code_map;
969 context->options = opts; 1001 context->options = opts;
970 context->int_cycle = 0xFFFFFFFF; 1002 context->int_cycle = CYCLE_NEVER;
971 context->status = 0x27; 1003 context->status = 0x27;
972 } 1004 return context;
1005 }