Mercurial > repos > blastem
comparison m68k_core.c @ 1130:8f14767661fa
Remove memory map assumptions from Z80 core and move a little bit of logic to the generic backend.c so it can be shared between CPU cores
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Wed, 28 Dec 2016 20:39:27 -0800 |
parents | c15896605bf2 |
children | 191ac490fb3d |
comparison
equal
deleted
inserted
replaced
1129:6b5c92b6205c | 1130:8f14767661fa |
---|---|
558 } | 558 } |
559 | 559 |
560 code_ptr get_native_address(m68k_options *opts, uint32_t address) | 560 code_ptr get_native_address(m68k_options *opts, uint32_t address) |
561 { | 561 { |
562 native_map_slot * native_code_map = opts->gen.native_code_map; | 562 native_map_slot * native_code_map = opts->gen.native_code_map; |
563 address &= opts->gen.address_mask; | |
564 | 563 |
565 //TODO: Refactor part of this loop into some kind of get_ram_chunk function | 564 memmap_chunk const *mem_chunk = find_map_chunk(address, &opts->gen, 0, NULL); |
566 for (int i = 0; i < opts->gen.memmap_chunks; i++) { | 565 if (mem_chunk) { |
567 if (address >= opts->gen.memmap[i].start && address < opts->gen.memmap[i].end) { | 566 //calculate the lowest alias for this address |
568 //calculate the lowest alias for this address | 567 address = mem_chunk->start + ((address - mem_chunk->start) & mem_chunk->mask); |
569 address = opts->gen.memmap[i].start + ((address - opts->gen.memmap[i].start) & opts->gen.memmap[i].mask); | 568 } |
570 } | |
571 } | |
572 | |
573 uint32_t chunk = address / NATIVE_CHUNK_SIZE; | 569 uint32_t chunk = address / NATIVE_CHUNK_SIZE; |
574 if (!native_code_map[chunk].base) { | 570 if (!native_code_map[chunk].base) { |
575 return NULL; | 571 return NULL; |
576 } | 572 } |
577 uint32_t offset = address % NATIVE_CHUNK_SIZE; | 573 uint32_t offset = address % NATIVE_CHUNK_SIZE; |
584 code_ptr get_native_from_context(m68k_context * context, uint32_t address) | 580 code_ptr get_native_from_context(m68k_context * context, uint32_t address) |
585 { | 581 { |
586 return get_native_address(context->options, address); | 582 return get_native_address(context->options, address); |
587 } | 583 } |
588 | 584 |
589 uint32_t get_instruction_start(m68k_options *opts, native_map_slot * native_code_map, uint32_t address) | 585 uint32_t get_instruction_start(m68k_options *opts, uint32_t address) |
590 { | 586 { |
591 address &= opts->gen.address_mask; | 587 native_map_slot * native_code_map = opts->gen.native_code_map; |
592 //TODO: Refactor part of this loop into some kind of get_ram_chunk function | 588 memmap_chunk const *mem_chunk = find_map_chunk(address, &opts->gen, 0, NULL); |
593 for (int i = 0; i < opts->gen.memmap_chunks; i++) { | 589 if (mem_chunk) { |
594 if (address >= opts->gen.memmap[i].start && address < opts->gen.memmap[i].end) { | 590 //calculate the lowest alias for this address |
595 //calculate the lowest alias for this address | 591 address = mem_chunk->start + ((address - mem_chunk->start) & mem_chunk->mask); |
596 address = opts->gen.memmap[i].start + ((address - opts->gen.memmap[i].start) & opts->gen.memmap[i].mask); | |
597 break; | |
598 } | |
599 } | 592 } |
600 | 593 |
601 uint32_t chunk = address / NATIVE_CHUNK_SIZE; | 594 uint32_t chunk = address / NATIVE_CHUNK_SIZE; |
602 if (!native_code_map[chunk].base) { | 595 if (!native_code_map[chunk].base) { |
603 return 0; | 596 return 0; |
604 } | 597 } |
605 uint32_t offset = address % NATIVE_CHUNK_SIZE; | 598 uint32_t offset = address % NATIVE_CHUNK_SIZE; |
606 if (native_code_map[chunk].offsets[offset] == INVALID_OFFSET) { | 599 if (native_code_map[chunk].offsets[offset] == INVALID_OFFSET) { |
607 return 0; | 600 return 0; |
608 } | 601 } |
609 while (native_code_map[chunk].offsets[offset] == EXTENSION_WORD) { | 602 while (native_code_map[chunk].offsets[offset] == EXTENSION_WORD) |
603 { | |
610 --address; | 604 --address; |
611 chunk = address / NATIVE_CHUNK_SIZE; | 605 chunk = address / NATIVE_CHUNK_SIZE; |
612 offset = address % NATIVE_CHUNK_SIZE; | 606 offset = address % NATIVE_CHUNK_SIZE; |
613 } | 607 } |
614 return address; | 608 return address; |
615 } | 609 } |
616 | 610 |
617 static void map_native_address(m68k_context * context, uint32_t address, code_ptr native_addr, uint8_t size, uint8_t native_size) | 611 static void map_native_address(m68k_context * context, uint32_t address, code_ptr native_addr, uint8_t size, uint8_t native_size) |
618 { | 612 { |
619 native_map_slot * native_code_map = context->native_code_map; | |
620 m68k_options * opts = context->options; | 613 m68k_options * opts = context->options; |
621 address &= opts->gen.address_mask; | 614 native_map_slot * native_code_map = opts->gen.native_code_map; |
622 uint32_t meta_off = 0; | 615 uint32_t meta_off; |
623 //TODO: Refactor part of this loop into some kind of get_ram_chunk function | 616 memmap_chunk const *mem_chunk = find_map_chunk(address, &opts->gen, MMAP_WRITE | MMAP_CODE, &meta_off); |
624 for (int i = 0; i < opts->gen.memmap_chunks; i++) { | 617 if (mem_chunk) { |
625 if (address >= opts->gen.memmap[i].start && address < opts->gen.memmap[i].end) { | 618 if ((mem_chunk->flags & (MMAP_WRITE | MMAP_CODE)) == (MMAP_WRITE | MMAP_CODE)) { |
626 if ((opts->gen.memmap[i].flags & (MMAP_WRITE | MMAP_CODE)) == (MMAP_WRITE | MMAP_CODE)) { | 619 uint32_t masked = (address & mem_chunk->mask); |
627 uint32_t masked = (address & opts->gen.memmap[i].mask); | 620 uint32_t final_off = masked + meta_off; |
628 uint32_t final_off = masked + meta_off; | 621 uint32_t ram_flags_off = final_off >> (opts->gen.ram_flags_shift + 3); |
629 uint32_t ram_flags_off = final_off >> (opts->gen.ram_flags_shift + 3); | 622 context->ram_code_flags[ram_flags_off] |= 1 << ((final_off >> opts->gen.ram_flags_shift) & 7); |
630 context->ram_code_flags[ram_flags_off] |= 1 << ((final_off >> opts->gen.ram_flags_shift) & 7); | 623 |
631 | 624 uint32_t slot = final_off / 1024; |
632 uint32_t slot = final_off / 1024; | 625 if (!opts->gen.ram_inst_sizes[slot]) { |
633 if (!opts->gen.ram_inst_sizes[slot]) { | 626 opts->gen.ram_inst_sizes[slot] = malloc(sizeof(uint8_t) * 512); |
634 opts->gen.ram_inst_sizes[slot] = malloc(sizeof(uint8_t) * 512); | |
635 } | |
636 opts->gen.ram_inst_sizes[slot][(final_off/2) & 511] = native_size; | |
637 | |
638 //TODO: Deal with case in which end of instruction is in a different memory chunk | |
639 masked = (address + size - 1) & opts->gen.memmap[i].mask; | |
640 final_off = masked + meta_off; | |
641 ram_flags_off = final_off >> (opts->gen.ram_flags_shift + 3); | |
642 context->ram_code_flags[ram_flags_off] |= 1 << ((final_off >> opts->gen.ram_flags_shift) & 7); | |
643 } | 627 } |
644 //calculate the lowest alias for this address | 628 opts->gen.ram_inst_sizes[slot][(final_off/2) & 511] = native_size; |
645 address = opts->gen.memmap[i].start + ((address - opts->gen.memmap[i].start) & opts->gen.memmap[i].mask); | 629 |
646 break; | 630 //TODO: Deal with case in which end of instruction is in a different memory chunk |
647 } else if ((opts->gen.memmap[i].flags & (MMAP_WRITE | MMAP_CODE)) == (MMAP_WRITE | MMAP_CODE)) { | 631 masked = (address + size - 1) & mem_chunk->mask; |
648 uint32_t size = chunk_size(&opts->gen, opts->gen.memmap + i); | 632 final_off = masked + meta_off; |
649 meta_off += size; | 633 ram_flags_off = final_off >> (opts->gen.ram_flags_shift + 3); |
650 } | 634 context->ram_code_flags[ram_flags_off] |= 1 << ((final_off >> opts->gen.ram_flags_shift) & 7); |
635 } | |
636 //calculate the lowest alias for this address | |
637 address = mem_chunk->start + ((address - mem_chunk->start) & mem_chunk->mask); | |
651 } | 638 } |
652 | 639 |
653 uint32_t chunk = address / NATIVE_CHUNK_SIZE; | 640 uint32_t chunk = address / NATIVE_CHUNK_SIZE; |
654 if (!native_code_map[chunk].base) { | 641 if (!native_code_map[chunk].base) { |
655 native_code_map[chunk].base = native_addr; | 642 native_code_map[chunk].base = native_addr; |
674 } | 661 } |
675 } | 662 } |
676 | 663 |
677 static uint8_t get_native_inst_size(m68k_options * opts, uint32_t address) | 664 static uint8_t get_native_inst_size(m68k_options * opts, uint32_t address) |
678 { | 665 { |
679 address &= opts->gen.address_mask; | 666 uint32_t meta_off; |
680 uint32_t meta_off = 0; | 667 memmap_chunk const *chunk = find_map_chunk(address, &opts->gen, MMAP_WRITE | MMAP_CODE, &meta_off); |
681 for (int i = 0; i < opts->gen.memmap_chunks; i++) { | 668 if (chunk) { |
682 if (address >= opts->gen.memmap[i].start && address < opts->gen.memmap[i].end) { | 669 meta_off += (address - chunk->start) & chunk->mask; |
683 if ((opts->gen.memmap[i].flags & (MMAP_WRITE | MMAP_CODE)) != (MMAP_WRITE | MMAP_CODE)) { | |
684 return 0; | |
685 } | |
686 meta_off += address & opts->gen.memmap[i].mask; | |
687 break; | |
688 } else if ((opts->gen.memmap[i].flags & (MMAP_WRITE | MMAP_CODE)) == (MMAP_WRITE | MMAP_CODE)) { | |
689 uint32_t size = chunk_size(&opts->gen, opts->gen.memmap + i); | |
690 meta_off += size; | |
691 } | |
692 } | 670 } |
693 uint32_t slot = meta_off/1024; | 671 uint32_t slot = meta_off/1024; |
694 return opts->gen.ram_inst_sizes[slot][(meta_off/2)%512]; | 672 return opts->gen.ram_inst_sizes[slot][(meta_off/2)%512]; |
695 } | 673 } |
696 | 674 |
710 } | 688 } |
711 } | 689 } |
712 | 690 |
713 uint16_t m68k_get_ir(m68k_context *context) | 691 uint16_t m68k_get_ir(m68k_context *context) |
714 { | 692 { |
715 uint32_t inst_addr = get_instruction_start(context->options, context->native_code_map, context->last_prefetch_address-2); | 693 uint32_t inst_addr = get_instruction_start(context->options, context->last_prefetch_address-2); |
716 uint16_t *native_addr = get_native_pointer(inst_addr, (void **)context->mem_pointers, &context->options->gen); | 694 uint16_t *native_addr = get_native_pointer(inst_addr, (void **)context->mem_pointers, &context->options->gen); |
717 if (native_addr) { | 695 if (native_addr) { |
718 return *native_addr; | 696 return *native_addr; |
719 } | 697 } |
720 fprintf(stderr, "M68K: Failed to calculate value of IR. Last prefetch address: %X\n", context->last_prefetch_address); | 698 fprintf(stderr, "M68K: Failed to calculate value of IR. Last prefetch address: %X\n", context->last_prefetch_address); |
1063 m68k_context * init_68k_context(m68k_options * opts, m68k_reset_handler reset_handler) | 1041 m68k_context * init_68k_context(m68k_options * opts, m68k_reset_handler reset_handler) |
1064 { | 1042 { |
1065 size_t ctx_size = sizeof(m68k_context) + ram_size(&opts->gen) / (1 << opts->gen.ram_flags_shift) / 8; | 1043 size_t ctx_size = sizeof(m68k_context) + ram_size(&opts->gen) / (1 << opts->gen.ram_flags_shift) / 8; |
1066 m68k_context * context = malloc(ctx_size); | 1044 m68k_context * context = malloc(ctx_size); |
1067 memset(context, 0, ctx_size); | 1045 memset(context, 0, ctx_size); |
1068 context->native_code_map = opts->gen.native_code_map; | |
1069 context->options = opts; | 1046 context->options = opts; |
1070 context->int_cycle = CYCLE_NEVER; | 1047 context->int_cycle = CYCLE_NEVER; |
1071 context->status = 0x27; | 1048 context->status = 0x27; |
1072 context->reset_handler = (code_ptr)reset_handler; | 1049 context->reset_handler = (code_ptr)reset_handler; |
1073 return context; | 1050 return context; |