Mercurial > repos > blastem
comparison z80_to_x86.c @ 266:376df762ddf5
Fix some more retranslation bugs in the Z80 core
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Wed, 01 May 2013 23:12:29 -0700 |
parents | 8fd6652e56f8 |
children | 1788e3f29c28 |
comparison
equal
deleted
inserted
replaced
265:c6d12878ea93 | 266:376df762ddf5 |
---|---|
1320 } | 1320 } |
1321 } | 1321 } |
1322 return addr; | 1322 return addr; |
1323 } | 1323 } |
1324 | 1324 |
1325 void z80_handle_deferred(z80_context * context) | |
1326 { | |
1327 x86_z80_options * opts = context->options; | |
1328 process_deferred(&opts->deferred, context, (native_addr_func)z80_get_native_address); | |
1329 if (opts->deferred) { | |
1330 translate_z80_stream(context, opts->deferred->address); | |
1331 } | |
1332 } | |
1333 | |
1325 void * z80_retranslate_inst(uint32_t address, z80_context * context) | 1334 void * z80_retranslate_inst(uint32_t address, z80_context * context) |
1326 { | 1335 { |
1336 char disbuf[80]; | |
1327 x86_z80_options * opts = context->options; | 1337 x86_z80_options * opts = context->options; |
1328 uint8_t orig_size = z80_get_native_inst_size(opts, address); | 1338 uint8_t orig_size = z80_get_native_inst_size(opts, address); |
1329 uint8_t * orig_start = z80_get_native_address(context, address); | 1339 uint8_t * orig_start = z80_get_native_address(context, address); |
1330 uint32_t orig = address; | 1340 uint32_t orig = address; |
1331 address &= 0x1FFF; | 1341 address &= 0x1FFF; |
1332 uint8_t * dst = opts->cur_code; | 1342 uint8_t * dst = opts->cur_code; |
1333 uint8_t * dst_end = opts->code_end; | 1343 uint8_t * dst_end = opts->code_end; |
1334 uint8_t *after, *inst = context->mem_pointers[0] + address; | 1344 uint8_t *after, *inst = context->mem_pointers[0] + address; |
1335 z80inst instbuf; | 1345 z80inst instbuf; |
1346 //printf("Retranslating code at Z80 address %X, native address %p\n", address, orig_start); | |
1336 after = z80_decode(inst, &instbuf); | 1347 after = z80_decode(inst, &instbuf); |
1348 /*z80_disasm(&instbuf, disbuf); | |
1349 if (instbuf.op == Z80_NOP) { | |
1350 printf("%X\t%s(%d)\n", address, disbuf, instbuf.immed); | |
1351 } else { | |
1352 printf("%X\t%s\n", address, disbuf); | |
1353 }*/ | |
1337 if (orig_size != ZMAX_NATIVE_SIZE) { | 1354 if (orig_size != ZMAX_NATIVE_SIZE) { |
1338 if (dst_end - dst < ZMAX_NATIVE_SIZE) { | 1355 if (dst_end - dst < ZMAX_NATIVE_SIZE) { |
1339 size_t size = 1024*1024; | 1356 size_t size = 1024*1024; |
1340 dst = alloc_code(&size); | 1357 dst = alloc_code(&size); |
1341 opts->code_end = dst_end = dst + size; | 1358 opts->code_end = dst_end = dst + size; |
1344 uint8_t * native_end = translate_z80inst(&instbuf, dst, context, address); | 1361 uint8_t * native_end = translate_z80inst(&instbuf, dst, context, address); |
1345 if ((native_end - dst) <= orig_size) { | 1362 if ((native_end - dst) <= orig_size) { |
1346 uint8_t * native_next = z80_get_native_address(context, address + after-inst); | 1363 uint8_t * native_next = z80_get_native_address(context, address + after-inst); |
1347 if (native_next && ((native_next == orig_start + orig_size) || (orig_size - (native_end - dst)) > 5)) { | 1364 if (native_next && ((native_next == orig_start + orig_size) || (orig_size - (native_end - dst)) > 5)) { |
1348 native_end = translate_z80inst(&instbuf, orig_start, context, address); | 1365 native_end = translate_z80inst(&instbuf, orig_start, context, address); |
1349 if (native_next == orig_start + orig_size) { | 1366 if (native_next == orig_start + orig_size && (native_next-native_end) < 2) { |
1350 while (native_end < orig_start + orig_size) { | 1367 while (native_end < orig_start + orig_size) { |
1351 *(native_end++) = 0x90; //NOP | 1368 *(native_end++) = 0x90; //NOP |
1352 } | 1369 } |
1353 } else { | 1370 } else { |
1354 jmp(native_end, native_next); | 1371 jmp(native_end, native_next); |
1355 } | 1372 } |
1373 z80_handle_deferred(context); | |
1356 return orig_start; | 1374 return orig_start; |
1357 } | 1375 } |
1358 } | 1376 } |
1359 z80_map_native_address(context, address, dst, after-inst, ZMAX_NATIVE_SIZE); | 1377 z80_map_native_address(context, address, dst, after-inst, ZMAX_NATIVE_SIZE); |
1360 opts->code_end = dst+ZMAX_NATIVE_SIZE; | 1378 opts->cur_code = dst+ZMAX_NATIVE_SIZE; |
1379 jmp(orig_start, dst); | |
1361 if(!(instbuf.op == Z80_RET || instbuf.op == Z80_RETI || instbuf.op == Z80_RETN || instbuf.op == Z80_JP || (instbuf.op == Z80_NOP && instbuf.immed == 42))) { | 1380 if(!(instbuf.op == Z80_RET || instbuf.op == Z80_RETI || instbuf.op == Z80_RETN || instbuf.op == Z80_JP || (instbuf.op == Z80_NOP && instbuf.immed == 42))) { |
1362 jmp(native_end, z80_get_native_address_trans(context, address + after-inst)); | 1381 jmp(native_end, z80_get_native_address_trans(context, address + after-inst)); |
1363 } | 1382 } |
1383 z80_handle_deferred(context); | |
1364 return dst; | 1384 return dst; |
1365 } else { | 1385 } else { |
1366 dst = translate_z80inst(&instbuf, orig_start, context, address); | 1386 dst = translate_z80inst(&instbuf, orig_start, context, address); |
1367 if(!(instbuf.op == Z80_RET || instbuf.op == Z80_RETI || instbuf.op == Z80_RETN || instbuf.op == Z80_JP || (instbuf.op == Z80_NOP && instbuf.immed == 42))) { | 1387 if(!(instbuf.op == Z80_RET || instbuf.op == Z80_RETI || instbuf.op == Z80_RETN || instbuf.op == Z80_JP || (instbuf.op == Z80_NOP && instbuf.immed == 42))) { |
1368 dst = jmp(dst, z80_get_native_address_trans(context, address + after-inst)); | 1388 dst = jmp(dst, z80_get_native_address_trans(context, address + after-inst)); |
1369 } | 1389 } |
1390 z80_handle_deferred(context); | |
1370 return orig_start; | 1391 return orig_start; |
1371 } | 1392 } |
1372 } | 1393 } |
1373 | 1394 |
1374 void translate_z80_stream(z80_context * context, uint32_t address) | 1395 void translate_z80_stream(z80_context * context, uint32_t address) |