comparison z80_to_x86.c @ 682:7ed1dbb48f61

Merge
author Michael Pavone <pavone@retrodev.com>
date Sun, 04 Jan 2015 23:35:55 -0800
parents 41a399c11ef1 6b248602ab84
children 7f96bd1cb1be
comparison
equal deleted inserted replaced
681:e26640daf1ae 682:7ed1dbb48f61
1375 uint8_t *no_jump_off = code->cur+1; 1375 uint8_t *no_jump_off = code->cur+1;
1376 jcc(code, cond, code->cur+2); 1376 jcc(code, cond, code->cur+2);
1377 cycles(&opts->gen, 5);//T States: 5 1377 cycles(&opts->gen, 5);//T States: 5
1378 uint16_t dest_addr = inst->immed; 1378 uint16_t dest_addr = inst->immed;
1379 code_ptr call_dst = z80_get_native_address(context, dest_addr); 1379 code_ptr call_dst = z80_get_native_address(context, dest_addr);
1380 if (!call_dst) { 1380 if (!call_dst) {
1381 opts->gen.deferred = defer_address(opts->gen.deferred, dest_addr, code->cur + 1); 1381 opts->gen.deferred = defer_address(opts->gen.deferred, dest_addr, code->cur + 1);
1382 //fake address to force large displacement 1382 //fake address to force large displacement
1383 call_dst = code->cur + 256; 1383 call_dst = code->cur + 256;
1384 } 1384 }
1385 jmp(code, call_dst); 1385 jmp(code, call_dst);
1386 *no_jump_off = code->cur - (no_jump_off+1); 1386 *no_jump_off = code->cur - (no_jump_off+1);
1387 break; 1387 break;
1388 } 1388 }
1389 case Z80_JR: { 1389 case Z80_JR: {
1390 cycles(&opts->gen, 12);//T States: 4,3,5 1390 cycles(&opts->gen, 12);//T States: 4,3,5
1391 uint16_t dest_addr = address + inst->immed + 2; 1391 uint16_t dest_addr = address + inst->immed + 2;
1392 code_ptr call_dst = z80_get_native_address(context, dest_addr); 1392 code_ptr call_dst = z80_get_native_address(context, dest_addr);
1393 if (!call_dst) { 1393 if (!call_dst) {
1394 opts->gen.deferred = defer_address(opts->gen.deferred, dest_addr, code->cur + 1); 1394 opts->gen.deferred = defer_address(opts->gen.deferred, dest_addr, code->cur + 1);
1395 //fake address to force large displacement 1395 //fake address to force large displacement
1396 call_dst = code->cur + 256; 1396 call_dst = code->cur + 256;
1397 } 1397 }
1398 jmp(code, call_dst); 1398 jmp(code, call_dst);
1399 break; 1399 break;
1400 } 1400 }
1401 case Z80_JRCC: { 1401 case Z80_JRCC: {
1402 cycles(&opts->gen, 7);//T States: 4,3 1402 cycles(&opts->gen, 7);//T States: 4,3
1417 uint8_t *no_jump_off = code->cur+1; 1417 uint8_t *no_jump_off = code->cur+1;
1418 jcc(code, cond, code->cur+2); 1418 jcc(code, cond, code->cur+2);
1419 cycles(&opts->gen, 5);//T States: 5 1419 cycles(&opts->gen, 5);//T States: 5
1420 uint16_t dest_addr = address + inst->immed + 2; 1420 uint16_t dest_addr = address + inst->immed + 2;
1421 code_ptr call_dst = z80_get_native_address(context, dest_addr); 1421 code_ptr call_dst = z80_get_native_address(context, dest_addr);
1422 if (!call_dst) { 1422 if (!call_dst) {
1423 opts->gen.deferred = defer_address(opts->gen.deferred, dest_addr, code->cur + 1); 1423 opts->gen.deferred = defer_address(opts->gen.deferred, dest_addr, code->cur + 1);
1424 //fake address to force large displacement 1424 //fake address to force large displacement
1425 call_dst = code->cur + 256; 1425 call_dst = code->cur + 256;
1426 } 1426 }
1427 jmp(code, call_dst); 1427 jmp(code, call_dst);
1428 *no_jump_off = code->cur - (no_jump_off+1); 1428 *no_jump_off = code->cur - (no_jump_off+1);
1429 break; 1429 break;
1430 } 1430 }
1431 case Z80_DJNZ: { 1431 case Z80_DJNZ: {
1434 uint8_t *no_jump_off = code->cur+1; 1434 uint8_t *no_jump_off = code->cur+1;
1435 jcc(code, CC_Z, code->cur+2); 1435 jcc(code, CC_Z, code->cur+2);
1436 cycles(&opts->gen, 5);//T States: 5 1436 cycles(&opts->gen, 5);//T States: 5
1437 uint16_t dest_addr = address + inst->immed + 2; 1437 uint16_t dest_addr = address + inst->immed + 2;
1438 code_ptr call_dst = z80_get_native_address(context, dest_addr); 1438 code_ptr call_dst = z80_get_native_address(context, dest_addr);
1439 if (!call_dst) { 1439 if (!call_dst) {
1440 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);
1441 //fake address to force large displacement 1441 //fake address to force large displacement
1442 call_dst = code->cur + 256; 1442 call_dst = code->cur + 256;
1443 } 1443 }
1444 jmp(code, call_dst); 1444 jmp(code, call_dst);
1445 *no_jump_off = code->cur - (no_jump_off+1); 1445 *no_jump_off = code->cur - (no_jump_off+1);
1446 break; 1446 break;
1447 } 1447 }
1448 case Z80_CALL: { 1448 case Z80_CALL: {
1449 cycles(&opts->gen, 11);//T States: 4,3,4 1449 cycles(&opts->gen, 11);//T States: 4,3,4
1450 sub_ir(code, 2, opts->regs[Z80_SP], SZ_W); 1450 sub_ir(code, 2, opts->regs[Z80_SP], SZ_W);
1451 mov_ir(code, address + 3, opts->gen.scratch1, SZ_W); 1451 mov_ir(code, address + 3, opts->gen.scratch1, SZ_W);
1452 mov_rr(code, opts->regs[Z80_SP], opts->gen.scratch2, SZ_W); 1452 mov_rr(code, opts->regs[Z80_SP], opts->gen.scratch2, SZ_W);
1453 call(code, opts->write_16_highfirst);//T States: 3, 3 1453 call(code, opts->write_16_highfirst);//T States: 3, 3
1454 code_ptr call_dst = z80_get_native_address(context, inst->immed); 1454 code_ptr call_dst = z80_get_native_address(context, inst->immed);
1455 if (!call_dst) { 1455 if (!call_dst) {
1456 opts->gen.deferred = defer_address(opts->gen.deferred, inst->immed, code->cur + 1); 1456 opts->gen.deferred = defer_address(opts->gen.deferred, inst->immed, code->cur + 1);
1457 //fake address to force large displacement 1457 //fake address to force large displacement
1458 call_dst = code->cur + 256; 1458 call_dst = code->cur + 256;
1459 } 1459 }
1460 jmp(code, call_dst); 1460 jmp(code, call_dst);
1461 break; 1461 break;
1462 } 1462 }
1463 case Z80_CALLCC: { 1463 case Z80_CALLCC: {
1464 cycles(&opts->gen, 10);//T States: 4,3,3 (false case) 1464 cycles(&opts->gen, 10);//T States: 4,3,3 (false case)
1492 sub_ir(code, 2, opts->regs[Z80_SP], SZ_W); 1492 sub_ir(code, 2, opts->regs[Z80_SP], SZ_W);
1493 mov_ir(code, address + 3, opts->gen.scratch1, SZ_W); 1493 mov_ir(code, address + 3, opts->gen.scratch1, SZ_W);
1494 mov_rr(code, opts->regs[Z80_SP], opts->gen.scratch2, SZ_W); 1494 mov_rr(code, opts->regs[Z80_SP], opts->gen.scratch2, SZ_W);
1495 call(code, opts->write_16_highfirst);//T States: 3, 3 1495 call(code, opts->write_16_highfirst);//T States: 3, 3
1496 code_ptr call_dst = z80_get_native_address(context, inst->immed); 1496 code_ptr call_dst = z80_get_native_address(context, inst->immed);
1497 if (!call_dst) { 1497 if (!call_dst) {
1498 opts->gen.deferred = defer_address(opts->gen.deferred, inst->immed, code->cur + 1); 1498 opts->gen.deferred = defer_address(opts->gen.deferred, inst->immed, code->cur + 1);
1499 //fake address to force large displacement 1499 //fake address to force large displacement
1500 call_dst = code->cur + 256; 1500 call_dst = code->cur + 256;
1501 } 1501 }
1502 jmp(code, call_dst); 1502 jmp(code, call_dst);
1503 *no_call_off = code->cur - (no_call_off+1); 1503 *no_call_off = code->cur - (no_call_off+1);
1504 break; 1504 break;
1505 } 1505 }
1506 case Z80_RET: 1506 case Z80_RET:
1507 cycles(&opts->gen, 4);//T States: 4 1507 cycles(&opts->gen, 4);//T States: 4
1508 mov_rr(code, opts->regs[Z80_SP], opts->gen.scratch1, SZ_W); 1508 mov_rr(code, opts->regs[Z80_SP], opts->gen.scratch1, SZ_W);
1509 call(code, opts->read_16);//T STates: 3, 3 1509 call(code, opts->read_16);//T STates: 3, 3
1510 add_ir(code, 2, opts->regs[Z80_SP], SZ_W); 1510 add_ir(code, 2, opts->regs[Z80_SP], SZ_W);
1804 if (opts->gen.deferred) { 1804 if (opts->gen.deferred) {
1805 translate_z80_stream(context, opts->gen.deferred->address); 1805 translate_z80_stream(context, opts->gen.deferred->address);
1806 } 1806 }
1807 } 1807 }
1808 1808
1809 extern void * z80_retranslate_inst(uint32_t address, z80_context * context, uint8_t * orig_start) asm("z80_retranslate_inst");
1809 void * z80_retranslate_inst(uint32_t address, z80_context * context, uint8_t * orig_start) 1810 void * z80_retranslate_inst(uint32_t address, z80_context * context, uint8_t * orig_start)
1810 { 1811 {
1811 char disbuf[80]; 1812 char disbuf[80];
1812 z80_options * opts = context->options; 1813 z80_options * opts = context->options;
1813 uint8_t orig_size = z80_get_native_inst_size(opts, address); 1814 uint8_t orig_size = z80_get_native_inst_size(opts, address);
1911 #endif 1912 #endif
1912 code_ptr start = opts->gen.code.cur; 1913 code_ptr start = opts->gen.code.cur;
1913 translate_z80inst(&inst, context, address, 0); 1914 translate_z80inst(&inst, context, address, 0);
1914 z80_map_native_address(context, address, start, next-encoded, opts->gen.code.cur - start); 1915 z80_map_native_address(context, address, start, next-encoded, opts->gen.code.cur - start);
1915 address += next-encoded; 1916 address += next-encoded;
1916 address &= 0xFFFF; 1917 address &= 0xFFFF;
1917 } while (!z80_is_terminal(&inst)); 1918 } while (!z80_is_terminal(&inst));
1918 process_deferred(&opts->gen.deferred, context, (native_addr_func)z80_get_native_address); 1919 process_deferred(&opts->gen.deferred, context, (native_addr_func)z80_get_native_address);
1919 if (opts->gen.deferred) { 1920 if (opts->gen.deferred) {
1920 address = opts->gen.deferred->address; 1921 address = opts->gen.deferred->address;
1921 dprintf("defferred address: %X\n", address); 1922 dprintf("defferred address: %X\n", address);
1922 } 1923 }
1923 } while (opts->gen.deferred); 1924 } while (opts->gen.deferred);
1924 } 1925 }
1925 1926
1926 void init_z80_opts(z80_options * options, memmap_chunk const * chunks, uint32_t num_chunks, uint32_t clock_divider) 1927 void init_z80_opts(z80_options * options, memmap_chunk const * chunks, uint32_t num_chunks, uint32_t clock_divider)
1927 { 1928 {
2275 void z80_clear_reset(z80_context * context, uint32_t cycle) 2276 void z80_clear_reset(z80_context * context, uint32_t cycle)
2276 { 2277 {
2277 z80_run(context, cycle); 2278 z80_run(context, cycle);
2278 if (context->reset) { 2279 if (context->reset) {
2279 //TODO: Handle case where reset is not asserted long enough 2280 //TODO: Handle case where reset is not asserted long enough
2280 context->im = 0; 2281 context->im = 0;
2281 context->iff1 = context->iff2 = 0; 2282 context->iff1 = context->iff2 = 0;
2282 context->native_pc = NULL; 2283 context->native_pc = NULL;
2283 context->extra_pc = NULL; 2284 context->extra_pc = NULL;
2284 context->pc = 0; 2285 context->pc = 0;
2285 context->reset = 0; 2286 context->reset = 0;
2286 if (context->busreq) { 2287 if (context->busreq) {
2287 //TODO: Figure out appropriate delay 2288 //TODO: Figure out appropriate delay
2288 context->busack = 1; 2289 context->busack = 1;
2292 2293
2293 void z80_assert_busreq(z80_context * context, uint32_t cycle) 2294 void z80_assert_busreq(z80_context * context, uint32_t cycle)
2294 { 2295 {
2295 z80_run(context, cycle); 2296 z80_run(context, cycle);
2296 context->busreq = 1; 2297 context->busreq = 1;
2297 } 2298 }
2298 2299
2299 void z80_clear_busreq(z80_context * context, uint32_t cycle) 2300 void z80_clear_busreq(z80_context * context, uint32_t cycle)
2300 { 2301 {
2301 z80_run(context, cycle); 2302 z80_run(context, cycle);
2302 context->busreq = 0; 2303 context->busreq = 0;
2351 z80_options * opts = context->options; 2352 z80_options * opts = context->options;
2352 code_info *code = &opts->gen.code; 2353 code_info *code = &opts->gen.code;
2353 check_code_prologue(code); 2354 check_code_prologue(code);
2354 context->bp_stub = code->cur; 2355 context->bp_stub = code->cur;
2355 2356
2356 //Calculate length of prologue 2357 //Calculate length of prologue
2357 check_cycles_int(&opts->gen, 0); 2358 check_cycles_int(&opts->gen, 0);
2358 int check_int_size = code->cur-context->bp_stub; 2359 int check_int_size = code->cur-context->bp_stub;
2359 code->cur = context->bp_stub; 2360 code->cur = context->bp_stub;
2360 2361
2361 //Calculate length of patch 2362 //Calculate length of patch
2362 int patch_size = zbreakpoint_patch(context, 0, code->cur); 2363 int patch_size = zbreakpoint_patch(context, 0, code->cur);
2363 2364
2364 //Save context and call breakpoint handler 2365 //Save context and call breakpoint handler
2365 call(code, opts->gen.save_context); 2366 call(code, opts->gen.save_context);
2366 push_r(code, opts->gen.scratch1); 2367 push_r(code, opts->gen.scratch1);
2367 call_args_abi(code, context->bp_handler, 2, opts->gen.context_reg, opts->gen.scratch1); 2368 call_args_abi(code, context->bp_handler, 2, opts->gen.context_reg, opts->gen.scratch1);
2368 mov_rr(code, RAX, opts->gen.context_reg, SZ_PTR); 2369 mov_rr(code, RAX, opts->gen.context_reg, SZ_PTR);
2369 //Restore context 2370 //Restore context
2370 call(code, opts->gen.load_context); 2371 call(code, opts->gen.load_context);
2371 pop_r(code, opts->gen.scratch1); 2372 pop_r(code, opts->gen.scratch1);
2372 //do prologue stuff 2373 //do prologue stuff
2373 cmp_rr(code, opts->gen.cycles, opts->gen.limit, SZ_D); 2374 cmp_rr(code, opts->gen.cycles, opts->gen.limit, SZ_D);
2374 uint8_t * jmp_off = code->cur+1; 2375 uint8_t * jmp_off = code->cur+1;
2375 jcc(code, CC_NC, code->cur + 7); 2376 jcc(code, CC_NC, code->cur + 7);
2376 pop_r(code, opts->gen.scratch1); 2377 pop_r(code, opts->gen.scratch1);
2377 add_ir(code, check_int_size - patch_size, opts->gen.scratch1, SZ_PTR); 2378 add_ir(code, check_int_size - patch_size, opts->gen.scratch1, SZ_PTR);
2378 push_r(code, opts->gen.scratch1); 2379 push_r(code, opts->gen.scratch1);
2379 jmp(code, opts->gen.handle_cycle_limit_int); 2380 jmp(code, opts->gen.handle_cycle_limit_int);
2380 *jmp_off = code->cur - (jmp_off+1); 2381 *jmp_off = code->cur - (jmp_off+1);
2381 //jump back to body of translated instruction 2382 //jump back to body of translated instruction
2382 pop_r(code, opts->gen.scratch1); 2383 pop_r(code, opts->gen.scratch1);
2383 add_ir(code, check_int_size - patch_size, opts->gen.scratch1, SZ_PTR); 2384 add_ir(code, check_int_size - patch_size, opts->gen.scratch1, SZ_PTR);
2384 jmp_r(code, opts->gen.scratch1); 2385 jmp_r(code, opts->gen.scratch1);
2385 } 2386 }
2386 2387
2409 code_info tmp_code = opts->gen.code; 2410 code_info tmp_code = opts->gen.code;
2410 opts->gen.code.cur = native; 2411 opts->gen.code.cur = native;
2411 opts->gen.code.last = native + 16; 2412 opts->gen.code.last = native + 16;
2412 check_cycles_int(&opts->gen, address); 2413 check_cycles_int(&opts->gen, address);
2413 opts->gen.code = tmp_code; 2414 opts->gen.code = tmp_code;
2414 } 2415 }
2415 } 2416 }
2416 2417