comparison m68k_to_x86.c @ 95:dd3c680c618c

Initial work on allowing dynamic branches and code in RAM plus a small fix to effective address decoding
author Mike Pavone <pavone@retrodev.com>
date Thu, 27 Dec 2012 21:19:58 -0800
parents f63b0e58e2d5
children f894f85cf39d
comparison
equal deleted inserted replaced
94:a668a35a3463 95:dd3c680c618c
1 #include "gen_x86.h" 1 #include "gen_x86.h"
2 #include "m68k_to_x86.h" 2 #include "m68k_to_x86.h"
3 #include "mem.h"
3 #include <stdio.h> 4 #include <stdio.h>
4 #include <stddef.h> 5 #include <stddef.h>
5 #include <stdlib.h> 6 #include <stdlib.h>
6 #include <string.h> 7 #include <string.h>
7 8
484 } 485 }
485 486
486 uint8_t * get_native_address(native_map_slot * native_code_map, uint32_t address) 487 uint8_t * get_native_address(native_map_slot * native_code_map, uint32_t address)
487 { 488 {
488 address &= 0xFFFFFF; 489 address &= 0xFFFFFF;
489 if (address > 0x400000) { 490 //if (address > 0x400000) {
490 printf("get_native_address: %X\n", address); 491 printf("get_native_address: %X\n", address);
491 } 492 //}
493 address /= 2;
492 uint32_t chunk = address / NATIVE_CHUNK_SIZE; 494 uint32_t chunk = address / NATIVE_CHUNK_SIZE;
493 if (!native_code_map[chunk].base) { 495 if (!native_code_map[chunk].base) {
494 return NULL; 496 return NULL;
495 } 497 }
496 uint32_t offset = address % NATIVE_CHUNK_SIZE; 498 uint32_t offset = address % NATIVE_CHUNK_SIZE;
537 } 539 }
538 540
539 void map_native_address(native_map_slot * native_code_map, uint32_t address, uint8_t * native_addr) 541 void map_native_address(native_map_slot * native_code_map, uint32_t address, uint8_t * native_addr)
540 { 542 {
541 address &= 0xFFFFFF; 543 address &= 0xFFFFFF;
544 address/= 2;
542 uint32_t chunk = address / NATIVE_CHUNK_SIZE; 545 uint32_t chunk = address / NATIVE_CHUNK_SIZE;
543 if (!native_code_map[chunk].base) { 546 if (!native_code_map[chunk].base) {
544 native_code_map[chunk].base = native_addr; 547 native_code_map[chunk].base = native_addr;
545 native_code_map[chunk].offsets = malloc(sizeof(int32_t) * NATIVE_CHUNK_SIZE); 548 native_code_map[chunk].offsets = malloc(sizeof(int32_t) * NATIVE_CHUNK_SIZE);
546 memset(native_code_map[chunk].offsets, 0xFF, sizeof(int32_t) * NATIVE_CHUNK_SIZE); 549 memset(native_code_map[chunk].offsets, 0xFF, sizeof(int32_t) * NATIVE_CHUNK_SIZE);
1878 exit(1); 1881 exit(1);
1879 } 1882 }
1880 return dst; 1883 return dst;
1881 } 1884 }
1882 1885
1883 uint8_t * translate_m68k_stream(uint8_t * dst, uint8_t * dst_end, uint32_t address, m68k_context * context) 1886 uint8_t * translate_m68k_stream(uint32_t address, m68k_context * context)
1884 { 1887 {
1885 m68kinst instbuf; 1888 m68kinst instbuf;
1886 x86_68k_options * opts = context->options; 1889 x86_68k_options * opts = context->options;
1890 uint8_t * dst = opts->cur_code;
1891 uint8_t * dst_end = opts->code_end;
1887 if(get_native_address(opts->native_code_map, address)) { 1892 if(get_native_address(opts->native_code_map, address)) {
1888 return dst; 1893 return dst;
1889 } 1894 }
1890 char disbuf[1024]; 1895 char disbuf[1024];
1891 uint16_t *encoded = context->mem_pointers[0] + address/2, *next; 1896 uint16_t *encoded, *next;
1897 if ((address & 0xFFFFFF) < 0x400000) {
1898 encoded = context->mem_pointers[0] + (address & 0xFFFFFF)/2;
1899 } else if ((address & 0xFFFFFF) > 0xE00000) {
1900 encoded = context->mem_pointers[1] + (address & 0xFFFF)/2;
1901 } else {
1902 printf("attempt to translate non-memory address: %X\n", address);
1903 exit(1);
1904 }
1892 do { 1905 do {
1893 do { 1906 do {
1894 if (dst_end-dst < 128) { 1907 if (dst_end-dst < 128) {
1895 puts("out of code memory"); 1908 puts("out of code memory");
1896 exit(1); 1909 exit(1);
1908 encoded = context->mem_pointers[0] + address/2; 1921 encoded = context->mem_pointers[0] + address/2;
1909 } else { 1922 } else {
1910 encoded = NULL; 1923 encoded = NULL;
1911 } 1924 }
1912 } while(encoded != NULL); 1925 } while(encoded != NULL);
1926 opts->cur_code = dst;
1913 return dst; 1927 return dst;
1928 }
1929
1930 uint8_t * get_native_address_trans(m68k_context * context, uint32_t address)
1931 {
1932 address &= 0xFFFFFF;
1933 uint8_t * ret = get_native_address(context->native_code_map, address);
1934 if (!ret) {
1935 translate_m68k_stream(address, context);
1936 ret = get_native_address(context->native_code_map, address);
1937 }
1938 return ret;
1914 } 1939 }
1915 1940
1916 void start_68k_context(m68k_context * context, uint32_t address) 1941 void start_68k_context(m68k_context * context, uint32_t address)
1917 { 1942 {
1918 uint8_t * addr = get_native_address(context->native_code_map, address); 1943 uint8_t * addr = get_native_address(context->native_code_map, address);
1939 opts->aregs[1] = R14; 1964 opts->aregs[1] = R14;
1940 opts->aregs[7] = R15; 1965 opts->aregs[7] = R15;
1941 opts->native_code_map = malloc(sizeof(native_map_slot) * NATIVE_MAP_CHUNKS); 1966 opts->native_code_map = malloc(sizeof(native_map_slot) * NATIVE_MAP_CHUNKS);
1942 memset(opts->native_code_map, 0, sizeof(native_map_slot) * NATIVE_MAP_CHUNKS); 1967 memset(opts->native_code_map, 0, sizeof(native_map_slot) * NATIVE_MAP_CHUNKS);
1943 opts->deferred = NULL; 1968 opts->deferred = NULL;
1969 size_t size = 1024 * 1024;
1970 opts->cur_code = alloc_code(&size);
1971 opts->code_end = opts->cur_code + size;
1944 } 1972 }
1945 1973
1946 void init_68k_context(m68k_context * context, native_map_slot * native_code_map, void * opts) 1974 void init_68k_context(m68k_context * context, native_map_slot * native_code_map, void * opts)
1947 { 1975 {
1948 memset(context, 0, sizeof(m68k_context)); 1976 memset(context, 0, sizeof(m68k_context));