Mercurial > repos > blastem
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 } |