Mercurial > repos > blastem
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)); |