comparison z80_to_x86.c @ 653:a18e3923481e

Remove some of the hard coded assumptions about the memory map from the CPU cores
author Michael Pavone <pavone@retrodev.com>
date Thu, 01 Jan 2015 14:36:55 -0800
parents f822d9216968
children 92ce5ea5ffc9
comparison
equal deleted inserted replaced
652:f822d9216968 653:a18e3923481e
1329 num_cycles += 6; 1329 num_cycles += 6;
1330 } else if(inst->ea_reg == Z80_IX || inst->ea_reg == Z80_IY) { 1330 } else if(inst->ea_reg == Z80_IX || inst->ea_reg == Z80_IY) {
1331 num_cycles += 4; 1331 num_cycles += 4;
1332 } 1332 }
1333 cycles(&opts->gen, num_cycles); 1333 cycles(&opts->gen, num_cycles);
1334 if (inst->addr_mode != Z80_REG_INDIRECT && inst->immed < 0x4000) { 1334 if (inst->addr_mode != Z80_REG_INDIRECT) {
1335 code_ptr call_dst = z80_get_native_address(context, inst->immed); 1335 code_ptr call_dst = z80_get_native_address(context, inst->immed);
1336 if (!call_dst) { 1336 if (!call_dst) {
1337 opts->gen.deferred = defer_address(opts->gen.deferred, inst->immed, code->cur + 1); 1337 opts->gen.deferred = defer_address(opts->gen.deferred, inst->immed, code->cur + 1);
1338 //fake address to force large displacement 1338 //fake address to force large displacement
1339 call_dst = code->cur + 256; 1339 call_dst = code->cur + 256;
1378 } 1378 }
1379 uint8_t *no_jump_off = code->cur+1; 1379 uint8_t *no_jump_off = code->cur+1;
1380 jcc(code, cond, code->cur+2); 1380 jcc(code, cond, code->cur+2);
1381 cycles(&opts->gen, 5);//T States: 5 1381 cycles(&opts->gen, 5);//T States: 5
1382 uint16_t dest_addr = inst->immed; 1382 uint16_t dest_addr = inst->immed;
1383 if (dest_addr < 0x4000) { 1383 code_ptr call_dst = z80_get_native_address(context, dest_addr);
1384 code_ptr call_dst = z80_get_native_address(context, dest_addr); 1384 if (!call_dst) {
1385 if (!call_dst) { 1385 opts->gen.deferred = defer_address(opts->gen.deferred, dest_addr, code->cur + 1);
1386 opts->gen.deferred = defer_address(opts->gen.deferred, dest_addr, code->cur + 1); 1386 //fake address to force large displacement
1387 //fake address to force large displacement 1387 call_dst = code->cur + 256;
1388 call_dst = code->cur + 256; 1388 }
1389 } 1389 jmp(code, call_dst);
1390 jmp(code, call_dst);
1391 } else {
1392 mov_ir(code, dest_addr, opts->gen.scratch1, SZ_W);
1393 call(code, opts->native_addr);
1394 jmp_r(code, opts->gen.scratch1);
1395 }
1396 *no_jump_off = code->cur - (no_jump_off+1); 1390 *no_jump_off = code->cur - (no_jump_off+1);
1397 break; 1391 break;
1398 } 1392 }
1399 case Z80_JR: { 1393 case Z80_JR: {
1400 cycles(&opts->gen, 12);//T States: 4,3,5 1394 cycles(&opts->gen, 12);//T States: 4,3,5
1401 uint16_t dest_addr = address + inst->immed + 2; 1395 uint16_t dest_addr = address + inst->immed + 2;
1402 if (dest_addr < 0x4000) { 1396 code_ptr call_dst = z80_get_native_address(context, dest_addr);
1403 code_ptr call_dst = z80_get_native_address(context, dest_addr); 1397 if (!call_dst) {
1404 if (!call_dst) { 1398 opts->gen.deferred = defer_address(opts->gen.deferred, dest_addr, code->cur + 1);
1405 opts->gen.deferred = defer_address(opts->gen.deferred, dest_addr, code->cur + 1); 1399 //fake address to force large displacement
1406 //fake address to force large displacement 1400 call_dst = code->cur + 256;
1407 call_dst = code->cur + 256; 1401 }
1408 } 1402 jmp(code, call_dst);
1409 jmp(code, call_dst);
1410 } else {
1411 mov_ir(code, dest_addr, opts->gen.scratch1, SZ_W);
1412 call(code, opts->native_addr);
1413 jmp_r(code, opts->gen.scratch1);
1414 }
1415 break; 1403 break;
1416 } 1404 }
1417 case Z80_JRCC: { 1405 case Z80_JRCC: {
1418 cycles(&opts->gen, 7);//T States: 4,3 1406 cycles(&opts->gen, 7);//T States: 4,3
1419 uint8_t cond = CC_Z; 1407 uint8_t cond = CC_Z;
1432 } 1420 }
1433 uint8_t *no_jump_off = code->cur+1; 1421 uint8_t *no_jump_off = code->cur+1;
1434 jcc(code, cond, code->cur+2); 1422 jcc(code, cond, code->cur+2);
1435 cycles(&opts->gen, 5);//T States: 5 1423 cycles(&opts->gen, 5);//T States: 5
1436 uint16_t dest_addr = address + inst->immed + 2; 1424 uint16_t dest_addr = address + inst->immed + 2;
1437 if (dest_addr < 0x4000) { 1425 code_ptr call_dst = z80_get_native_address(context, dest_addr);
1438 code_ptr call_dst = z80_get_native_address(context, dest_addr); 1426 if (!call_dst) {
1439 if (!call_dst) { 1427 opts->gen.deferred = defer_address(opts->gen.deferred, dest_addr, code->cur + 1);
1440 opts->gen.deferred = defer_address(opts->gen.deferred, dest_addr, code->cur + 1); 1428 //fake address to force large displacement
1441 //fake address to force large displacement 1429 call_dst = code->cur + 256;
1442 call_dst = code->cur + 256; 1430 }
1443 } 1431 jmp(code, call_dst);
1444 jmp(code, call_dst);
1445 } else {
1446 mov_ir(code, dest_addr, opts->gen.scratch1, SZ_W);
1447 call(code, opts->native_addr);
1448 jmp_r(code, opts->gen.scratch1);
1449 }
1450 *no_jump_off = code->cur - (no_jump_off+1); 1432 *no_jump_off = code->cur - (no_jump_off+1);
1451 break; 1433 break;
1452 } 1434 }
1453 case Z80_DJNZ: 1435 case Z80_DJNZ: {
1454 cycles(&opts->gen, 8);//T States: 5,3 1436 cycles(&opts->gen, 8);//T States: 5,3
1455 sub_ir(code, 1, opts->regs[Z80_B], SZ_B); 1437 sub_ir(code, 1, opts->regs[Z80_B], SZ_B);
1456 uint8_t *no_jump_off = code->cur+1; 1438 uint8_t *no_jump_off = code->cur+1;
1457 jcc(code, CC_Z, code->cur+2); 1439 jcc(code, CC_Z, code->cur+2);
1458 cycles(&opts->gen, 5);//T States: 5 1440 cycles(&opts->gen, 5);//T States: 5
1459 uint16_t dest_addr = address + inst->immed + 2; 1441 uint16_t dest_addr = address + inst->immed + 2;
1460 if (dest_addr < 0x4000) { 1442 code_ptr call_dst = z80_get_native_address(context, dest_addr);
1461 code_ptr call_dst = z80_get_native_address(context, dest_addr); 1443 if (!call_dst) {
1462 if (!call_dst) { 1444 opts->gen.deferred = defer_address(opts->gen.deferred, dest_addr, code->cur + 1);
1463 opts->gen.deferred = defer_address(opts->gen.deferred, dest_addr, code->cur + 1); 1445 //fake address to force large displacement
1464 //fake address to force large displacement 1446 call_dst = code->cur + 256;
1465 call_dst = code->cur + 256; 1447 }
1466 } 1448 jmp(code, call_dst);
1467 jmp(code, call_dst);
1468 } else {
1469 mov_ir(code, dest_addr, opts->gen.scratch1, SZ_W);
1470 call(code, opts->native_addr);
1471 jmp_r(code, opts->gen.scratch1);
1472 }
1473 *no_jump_off = code->cur - (no_jump_off+1); 1449 *no_jump_off = code->cur - (no_jump_off+1);
1474 break; 1450 break;
1451 }
1475 case Z80_CALL: { 1452 case Z80_CALL: {
1476 cycles(&opts->gen, 11);//T States: 4,3,4 1453 cycles(&opts->gen, 11);//T States: 4,3,4
1477 sub_ir(code, 2, opts->regs[Z80_SP], SZ_W); 1454 sub_ir(code, 2, opts->regs[Z80_SP], SZ_W);
1478 mov_ir(code, address + 3, opts->gen.scratch1, SZ_W); 1455 mov_ir(code, address + 3, opts->gen.scratch1, SZ_W);
1479 mov_rr(code, opts->regs[Z80_SP], opts->gen.scratch2, SZ_W); 1456 mov_rr(code, opts->regs[Z80_SP], opts->gen.scratch2, SZ_W);
1480 call(code, opts->write_16_highfirst);//T States: 3, 3 1457 call(code, opts->write_16_highfirst);//T States: 3, 3
1481 if (inst->immed < 0x4000) { 1458 code_ptr call_dst = z80_get_native_address(context, inst->immed);
1482 code_ptr call_dst = z80_get_native_address(context, inst->immed); 1459 if (!call_dst) {
1483 if (!call_dst) { 1460 opts->gen.deferred = defer_address(opts->gen.deferred, inst->immed, code->cur + 1);
1484 opts->gen.deferred = defer_address(opts->gen.deferred, inst->immed, code->cur + 1); 1461 //fake address to force large displacement
1485 //fake address to force large displacement 1462 call_dst = code->cur + 256;
1486 call_dst = code->cur + 256; 1463 }
1487 } 1464 jmp(code, call_dst);
1488 jmp(code, call_dst); 1465 break;
1489 } else { 1466 }
1490 mov_ir(code, inst->immed, opts->gen.scratch1, SZ_W); 1467 case Z80_CALLCC: {
1491 call(code, opts->native_addr);
1492 jmp_r(code, opts->gen.scratch1);
1493 }
1494 break;
1495 }
1496 case Z80_CALLCC:
1497 cycles(&opts->gen, 10);//T States: 4,3,3 (false case) 1468 cycles(&opts->gen, 10);//T States: 4,3,3 (false case)
1498 uint8_t cond = CC_Z; 1469 uint8_t cond = CC_Z;
1499 switch (inst->reg) 1470 switch (inst->reg)
1500 { 1471 {
1501 case Z80_CC_NZ: 1472 case Z80_CC_NZ:
1524 cycles(&opts->gen, 1);//Last of the above T states takes an extra cycle in the true case 1495 cycles(&opts->gen, 1);//Last of the above T states takes an extra cycle in the true case
1525 sub_ir(code, 2, opts->regs[Z80_SP], SZ_W); 1496 sub_ir(code, 2, opts->regs[Z80_SP], SZ_W);
1526 mov_ir(code, address + 3, opts->gen.scratch1, SZ_W); 1497 mov_ir(code, address + 3, opts->gen.scratch1, SZ_W);
1527 mov_rr(code, opts->regs[Z80_SP], opts->gen.scratch2, SZ_W); 1498 mov_rr(code, opts->regs[Z80_SP], opts->gen.scratch2, SZ_W);
1528 call(code, opts->write_16_highfirst);//T States: 3, 3 1499 call(code, opts->write_16_highfirst);//T States: 3, 3
1529 if (inst->immed < 0x4000) { 1500 code_ptr call_dst = z80_get_native_address(context, inst->immed);
1530 code_ptr call_dst = z80_get_native_address(context, inst->immed); 1501 if (!call_dst) {
1531 if (!call_dst) { 1502 opts->gen.deferred = defer_address(opts->gen.deferred, inst->immed, code->cur + 1);
1532 opts->gen.deferred = defer_address(opts->gen.deferred, inst->immed, code->cur + 1); 1503 //fake address to force large displacement
1533 //fake address to force large displacement 1504 call_dst = code->cur + 256;
1534 call_dst = code->cur + 256; 1505 }
1535 } 1506 jmp(code, call_dst);
1536 jmp(code, call_dst);
1537 } else {
1538 mov_ir(code, inst->immed, opts->gen.scratch1, SZ_W);
1539 call(code, opts->native_addr);
1540 jmp_r(code, opts->gen.scratch1);
1541 }
1542 *no_call_off = code->cur - (no_call_off+1); 1507 *no_call_off = code->cur - (no_call_off+1);
1543 break; 1508 break;
1509 }
1544 case Z80_RET: 1510 case Z80_RET:
1545 cycles(&opts->gen, 4);//T States: 4 1511 cycles(&opts->gen, 4);//T States: 4
1546 mov_rr(code, opts->regs[Z80_SP], opts->gen.scratch1, SZ_W); 1512 mov_rr(code, opts->regs[Z80_SP], opts->gen.scratch1, SZ_W);
1547 call(code, opts->read_16);//T STates: 3, 3 1513 call(code, opts->read_16);//T STates: 3, 3
1548 add_ir(code, 2, opts->regs[Z80_SP], SZ_W); 1514 add_ir(code, 2, opts->regs[Z80_SP], SZ_W);
1848 void * z80_retranslate_inst(uint32_t address, z80_context * context, uint8_t * orig_start) 1814 void * z80_retranslate_inst(uint32_t address, z80_context * context, uint8_t * orig_start)
1849 { 1815 {
1850 char disbuf[80]; 1816 char disbuf[80];
1851 z80_options * opts = context->options; 1817 z80_options * opts = context->options;
1852 uint8_t orig_size = z80_get_native_inst_size(opts, address); 1818 uint8_t orig_size = z80_get_native_inst_size(opts, address);
1853 uint32_t orig = address;
1854 address &= 0x1FFF;
1855 code_info *code = &opts->gen.code; 1819 code_info *code = &opts->gen.code;
1856 uint8_t *after, *inst = context->mem_pointers[0] + address; 1820 uint8_t *after, *inst = get_native_pointer(address, (void **)context->mem_pointers, &opts->gen);
1857 z80inst instbuf; 1821 z80inst instbuf;
1858 dprintf("Retranslating code at Z80 address %X, native address %p\n", address, orig_start); 1822 dprintf("Retranslating code at Z80 address %X, native address %p\n", address, orig_start);
1859 after = z80_decode(inst, &instbuf); 1823 after = z80_decode(inst, &instbuf);
1860 #ifdef DO_DEBUG_PRINT 1824 #ifdef DO_DEBUG_PRINT
1861 z80_disasm(&instbuf, disbuf, address); 1825 z80_disasm(&instbuf, disbuf, address);
1919 if (z80_get_native_address(context, address)) { 1883 if (z80_get_native_address(context, address)) {
1920 return; 1884 return;
1921 } 1885 }
1922 z80_options * opts = context->options; 1886 z80_options * opts = context->options;
1923 uint32_t start_address = address; 1887 uint32_t start_address = address;
1924 uint8_t * encoded = NULL, *next; 1888
1925 if (address < 0x4000) { 1889 do
1926 encoded = context->mem_pointers[0] + (address & 0x1FFF);
1927 }
1928
1929 while (encoded != NULL || address >= 0x4000)
1930 { 1890 {
1931 z80inst inst; 1891 z80inst inst;
1932 dprintf("translating Z80 code at address %X\n", address); 1892 dprintf("translating Z80 code at address %X\n", address);
1933 do { 1893 do {
1934 if (address >= 0x4000) {
1935 code_info stub = z80_make_interp_stub(context, address);
1936 z80_map_native_address(context, address, stub.cur, 1, stub.last - stub.cur);
1937 break;
1938 }
1939 uint8_t * existing = z80_get_native_address(context, address); 1894 uint8_t * existing = z80_get_native_address(context, address);
1940 if (existing) { 1895 if (existing) {
1941 jmp(&opts->gen.code, existing); 1896 jmp(&opts->gen.code, existing);
1897 break;
1898 }
1899 uint8_t * encoded, *next;
1900 encoded = get_native_pointer(address, (void **)context->mem_pointers, &opts->gen);
1901 if (!encoded) {
1902 code_info stub = z80_make_interp_stub(context, address);
1903 z80_map_native_address(context, address, stub.cur, 1, stub.last - stub.cur);
1942 break; 1904 break;
1943 } 1905 }
1944 //make sure prologue is in a contiguous chunk of code 1906 //make sure prologue is in a contiguous chunk of code
1945 check_code_prologue(&opts->gen.code); 1907 check_code_prologue(&opts->gen.code);
1946 next = z80_decode(encoded, &inst); 1908 next = z80_decode(encoded, &inst);
1954 #endif 1916 #endif
1955 code_ptr start = opts->gen.code.cur; 1917 code_ptr start = opts->gen.code.cur;
1956 translate_z80inst(&inst, context, address, 0); 1918 translate_z80inst(&inst, context, address, 0);
1957 z80_map_native_address(context, address, start, next-encoded, opts->gen.code.cur - start); 1919 z80_map_native_address(context, address, start, next-encoded, opts->gen.code.cur - start);
1958 address += next-encoded; 1920 address += next-encoded;
1959 if (address > 0xFFFF) { 1921 address &= 0xFFFF;
1960 address &= 0xFFFF;
1961
1962 } else {
1963 encoded = next;
1964 }
1965 } while (!z80_is_terminal(&inst)); 1922 } while (!z80_is_terminal(&inst));
1966 process_deferred(&opts->gen.deferred, context, (native_addr_func)z80_get_native_address); 1923 process_deferred(&opts->gen.deferred, context, (native_addr_func)z80_get_native_address);
1967 if (opts->gen.deferred) { 1924 if (opts->gen.deferred) {
1968 address = opts->gen.deferred->address; 1925 address = opts->gen.deferred->address;
1969 dprintf("defferred address: %X\n", address); 1926 dprintf("defferred address: %X\n", address);
1970 if (address < 0x4000) { 1927 }
1971 encoded = context->mem_pointers[0] + (address & 0x1FFF); 1928 } while (opts->gen.deferred);
1972 } else {
1973 encoded = NULL;
1974 }
1975 } else {
1976 encoded = NULL;
1977 address = 0;
1978 }
1979 }
1980 } 1929 }
1981 1930
1982 void init_x86_z80_opts(z80_options * options, memmap_chunk const * chunks, uint32_t num_chunks) 1931 void init_x86_z80_opts(z80_options * options, memmap_chunk const * chunks, uint32_t num_chunks)
1983 { 1932 {
1984 memset(options, 0, sizeof(*options)); 1933 memset(options, 0, sizeof(*options));
1985 1934
1935 options->gen.memmap = chunks;
1936 options->gen.memmap_chunks = num_chunks;
1986 options->gen.address_size = SZ_W; 1937 options->gen.address_size = SZ_W;
1987 options->gen.address_mask = 0xFFFF; 1938 options->gen.address_mask = 0xFFFF;
1988 options->gen.max_address = 0x10000; 1939 options->gen.max_address = 0x10000;
1989 options->gen.bus_cycles = 3; 1940 options->gen.bus_cycles = 3;
1990 options->gen.mem_ptr_off = offsetof(z80_context, mem_pointers); 1941 options->gen.mem_ptr_off = offsetof(z80_context, mem_pointers);