Mercurial > repos > blastem
comparison z80_to_x86.c @ 601:f0061e3d2ad9
Fix a few bugs introduced in the Z80 core from the adjustments to fit with the code gen refactor
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Fri, 26 Dec 2014 15:45:31 -0800 |
parents | faad1927d836 |
children | 9d6fed6501ba |
comparison
equal
deleted
inserted
replaced
600:a9dcaacdc0c5 | 601:f0061e3d2ad9 |
---|---|
1301 if (inst->addr_mode != Z80_REG_INDIRECT && inst->immed < 0x4000) { | 1301 if (inst->addr_mode != Z80_REG_INDIRECT && inst->immed < 0x4000) { |
1302 code_ptr call_dst = z80_get_native_address(context, inst->immed); | 1302 code_ptr call_dst = z80_get_native_address(context, inst->immed); |
1303 if (!call_dst) { | 1303 if (!call_dst) { |
1304 opts->gen.deferred = defer_address(opts->gen.deferred, inst->immed, code->cur + 1); | 1304 opts->gen.deferred = defer_address(opts->gen.deferred, inst->immed, code->cur + 1); |
1305 //fake address to force large displacement | 1305 //fake address to force large displacement |
1306 call_dst + 256; | 1306 call_dst = code->cur + 256; |
1307 } | 1307 } |
1308 jmp(code, call_dst); | 1308 jmp(code, call_dst); |
1309 } else { | 1309 } else { |
1310 if (inst->addr_mode == Z80_REG_INDIRECT) { | 1310 if (inst->addr_mode == Z80_REG_INDIRECT) { |
1311 mov_rr(code, opts->regs[inst->ea_reg], opts->gen.scratch1, SZ_W); | 1311 mov_rr(code, opts->regs[inst->ea_reg], opts->gen.scratch1, SZ_W); |
1350 if (dest_addr < 0x4000) { | 1350 if (dest_addr < 0x4000) { |
1351 code_ptr call_dst = z80_get_native_address(context, dest_addr); | 1351 code_ptr call_dst = z80_get_native_address(context, dest_addr); |
1352 if (!call_dst) { | 1352 if (!call_dst) { |
1353 opts->gen.deferred = defer_address(opts->gen.deferred, dest_addr, code->cur + 1); | 1353 opts->gen.deferred = defer_address(opts->gen.deferred, dest_addr, code->cur + 1); |
1354 //fake address to force large displacement | 1354 //fake address to force large displacement |
1355 call_dst + 256; | 1355 call_dst = code->cur + 256; |
1356 } | 1356 } |
1357 jmp(code, call_dst); | 1357 jmp(code, call_dst); |
1358 } else { | 1358 } else { |
1359 mov_ir(code, dest_addr, opts->gen.scratch1, SZ_W); | 1359 mov_ir(code, dest_addr, opts->gen.scratch1, SZ_W); |
1360 call(code, opts->native_addr); | 1360 call(code, opts->native_addr); |
1369 if (dest_addr < 0x4000) { | 1369 if (dest_addr < 0x4000) { |
1370 code_ptr call_dst = z80_get_native_address(context, dest_addr); | 1370 code_ptr call_dst = z80_get_native_address(context, dest_addr); |
1371 if (!call_dst) { | 1371 if (!call_dst) { |
1372 opts->gen.deferred = defer_address(opts->gen.deferred, dest_addr, code->cur + 1); | 1372 opts->gen.deferred = defer_address(opts->gen.deferred, dest_addr, code->cur + 1); |
1373 //fake address to force large displacement | 1373 //fake address to force large displacement |
1374 call_dst + 256; | 1374 call_dst = code->cur + 256; |
1375 } | 1375 } |
1376 jmp(code, call_dst); | 1376 jmp(code, call_dst); |
1377 } else { | 1377 } else { |
1378 mov_ir(code, dest_addr, opts->gen.scratch1, SZ_W); | 1378 mov_ir(code, dest_addr, opts->gen.scratch1, SZ_W); |
1379 call(code, opts->native_addr); | 1379 call(code, opts->native_addr); |
1404 if (dest_addr < 0x4000) { | 1404 if (dest_addr < 0x4000) { |
1405 code_ptr call_dst = z80_get_native_address(context, dest_addr); | 1405 code_ptr call_dst = z80_get_native_address(context, dest_addr); |
1406 if (!call_dst) { | 1406 if (!call_dst) { |
1407 opts->gen.deferred = defer_address(opts->gen.deferred, dest_addr, code->cur + 1); | 1407 opts->gen.deferred = defer_address(opts->gen.deferred, dest_addr, code->cur + 1); |
1408 //fake address to force large displacement | 1408 //fake address to force large displacement |
1409 call_dst + 256; | 1409 call_dst = code->cur + 256; |
1410 } | 1410 } |
1411 jmp(code, call_dst); | 1411 jmp(code, call_dst); |
1412 } else { | 1412 } else { |
1413 mov_ir(code, dest_addr, opts->gen.scratch1, SZ_W); | 1413 mov_ir(code, dest_addr, opts->gen.scratch1, SZ_W); |
1414 call(code, opts->native_addr); | 1414 call(code, opts->native_addr); |
1427 if (dest_addr < 0x4000) { | 1427 if (dest_addr < 0x4000) { |
1428 code_ptr call_dst = z80_get_native_address(context, dest_addr); | 1428 code_ptr call_dst = z80_get_native_address(context, dest_addr); |
1429 if (!call_dst) { | 1429 if (!call_dst) { |
1430 opts->gen.deferred = defer_address(opts->gen.deferred, dest_addr, code->cur + 1); | 1430 opts->gen.deferred = defer_address(opts->gen.deferred, dest_addr, code->cur + 1); |
1431 //fake address to force large displacement | 1431 //fake address to force large displacement |
1432 call_dst + 256; | 1432 call_dst = code->cur + 256; |
1433 } | 1433 } |
1434 jmp(code, call_dst); | 1434 jmp(code, call_dst); |
1435 } else { | 1435 } else { |
1436 mov_ir(code, dest_addr, opts->gen.scratch1, SZ_W); | 1436 mov_ir(code, dest_addr, opts->gen.scratch1, SZ_W); |
1437 call(code, opts->native_addr); | 1437 call(code, opts->native_addr); |
1448 if (inst->immed < 0x4000) { | 1448 if (inst->immed < 0x4000) { |
1449 code_ptr call_dst = z80_get_native_address(context, inst->immed); | 1449 code_ptr call_dst = z80_get_native_address(context, inst->immed); |
1450 if (!call_dst) { | 1450 if (!call_dst) { |
1451 opts->gen.deferred = defer_address(opts->gen.deferred, inst->immed, code->cur + 1); | 1451 opts->gen.deferred = defer_address(opts->gen.deferred, inst->immed, code->cur + 1); |
1452 //fake address to force large displacement | 1452 //fake address to force large displacement |
1453 call_dst + 256; | 1453 call_dst = code->cur + 256; |
1454 } | 1454 } |
1455 jmp(code, call_dst); | 1455 jmp(code, call_dst); |
1456 } else { | 1456 } else { |
1457 mov_ir(code, inst->immed, opts->gen.scratch1, SZ_W); | 1457 mov_ir(code, inst->immed, opts->gen.scratch1, SZ_W); |
1458 call(code, opts->native_addr); | 1458 call(code, opts->native_addr); |
1496 if (inst->immed < 0x4000) { | 1496 if (inst->immed < 0x4000) { |
1497 code_ptr call_dst = z80_get_native_address(context, inst->immed); | 1497 code_ptr call_dst = z80_get_native_address(context, inst->immed); |
1498 if (!call_dst) { | 1498 if (!call_dst) { |
1499 opts->gen.deferred = defer_address(opts->gen.deferred, inst->immed, code->cur + 1); | 1499 opts->gen.deferred = defer_address(opts->gen.deferred, inst->immed, code->cur + 1); |
1500 //fake address to force large displacement | 1500 //fake address to force large displacement |
1501 call_dst + 256; | 1501 call_dst = code->cur + 256; |
1502 } | 1502 } |
1503 jmp(code, call_dst); | 1503 jmp(code, call_dst); |
1504 } else { | 1504 } else { |
1505 mov_ir(code, inst->immed, opts->gen.scratch1, SZ_W); | 1505 mov_ir(code, inst->immed, opts->gen.scratch1, SZ_W); |
1506 call(code, opts->native_addr); | 1506 call(code, opts->native_addr); |
1580 call(code, opts->write_16_highfirst);//T States: 3, 3 | 1580 call(code, opts->write_16_highfirst);//T States: 3, 3 |
1581 code_ptr call_dst = z80_get_native_address(context, inst->immed); | 1581 code_ptr call_dst = z80_get_native_address(context, inst->immed); |
1582 if (!call_dst) { | 1582 if (!call_dst) { |
1583 opts->gen.deferred = defer_address(opts->gen.deferred, inst->immed, code->cur + 1); | 1583 opts->gen.deferred = defer_address(opts->gen.deferred, inst->immed, code->cur + 1); |
1584 //fake address to force large displacement | 1584 //fake address to force large displacement |
1585 call_dst + 256; | 1585 call_dst = code->cur + 256; |
1586 } | 1586 } |
1587 jmp(code, call_dst); | 1587 jmp(code, call_dst); |
1588 break; | 1588 break; |
1589 } | 1589 } |
1590 case Z80_IN: | 1590 case Z80_IN: |
1813 } else { | 1813 } else { |
1814 code_info tmp_code = *code; | 1814 code_info tmp_code = *code; |
1815 code->cur = orig_start; | 1815 code->cur = orig_start; |
1816 code->last = orig_start + ZMAX_NATIVE_SIZE; | 1816 code->last = orig_start + ZMAX_NATIVE_SIZE; |
1817 translate_z80inst(&instbuf, context, address); | 1817 translate_z80inst(&instbuf, context, address); |
1818 code_info tmp2 = *code; | |
1819 *code = tmp_code; | |
1818 if (!z80_is_terminal(&instbuf)) { | 1820 if (!z80_is_terminal(&instbuf)) { |
1819 jmp(code, z80_get_native_address_trans(context, address + after-inst)); | 1821 |
1820 } | 1822 jmp(&tmp2, z80_get_native_address_trans(context, address + after-inst)); |
1821 *code = tmp_code; | 1823 } |
1822 z80_handle_deferred(context); | 1824 z80_handle_deferred(context); |
1823 return orig_start; | 1825 return orig_start; |
1824 } | 1826 } |
1825 } | 1827 } |
1826 | 1828 |
1853 uint8_t * existing = z80_get_native_address(context, address); | 1855 uint8_t * existing = z80_get_native_address(context, address); |
1854 if (existing) { | 1856 if (existing) { |
1855 jmp(&opts->gen.code, existing); | 1857 jmp(&opts->gen.code, existing); |
1856 break; | 1858 break; |
1857 } | 1859 } |
1860 //make sure prologue is in a contiguous chunk of code | |
1861 check_code_prologue(&opts->gen.code); | |
1858 next = z80_decode(encoded, &inst); | 1862 next = z80_decode(encoded, &inst); |
1859 #ifdef DO_DEBUG_PRINT | 1863 #ifdef DO_DEBUG_PRINT |
1860 z80_disasm(&inst, disbuf, address); | 1864 z80_disasm(&inst, disbuf, address); |
1861 if (inst.op == Z80_NOP) { | 1865 if (inst.op == Z80_NOP) { |
1862 printf("%X\t%s(%d)\n", address, disbuf, inst.immed); | 1866 printf("%X\t%s(%d)\n", address, disbuf, inst.immed); |
2226 | 2230 |
2227 void zinsert_breakpoint(z80_context * context, uint16_t address, uint8_t * bp_handler) | 2231 void zinsert_breakpoint(z80_context * context, uint16_t address, uint8_t * bp_handler) |
2228 { | 2232 { |
2229 static uint8_t * bp_stub = NULL; | 2233 static uint8_t * bp_stub = NULL; |
2230 z80_options * opts = context->options; | 2234 z80_options * opts = context->options; |
2231 uint8_t * native = z80_get_native_address_trans(context, address); | 2235 code_ptr native = z80_get_native_address_trans(context, address); |
2232 code_info tmp_code = {native, native+16}; | 2236 code_info tmp_code = {native, native+16}; |
2233 mov_ir(&tmp_code, address, opts->gen.scratch1, SZ_W); | 2237 mov_ir(&tmp_code, address, opts->gen.scratch1, SZ_W); |
2234 if (!bp_stub) { | 2238 if (!bp_stub) { |
2235 code_info *code = &opts->gen.code; | 2239 code_info *code = &opts->gen.code; |
2236 //TODO: do an alloc check here to make sure the prologue length calc works | 2240 check_code_prologue(code); |
2237 bp_stub = code->cur; | 2241 bp_stub = code->cur; |
2238 call(&tmp_code, bp_stub); | 2242 call(&tmp_code, bp_stub); |
2239 | 2243 |
2240 //Calculate length of prologue | 2244 //Calculate length of prologue |
2241 check_cycles_int(&opts->gen, address); | 2245 check_cycles_int(&opts->gen, address); |
2255 //do prologue stuff | 2259 //do prologue stuff |
2256 cmp_rr(code, opts->gen.cycles, opts->gen.limit, SZ_D); | 2260 cmp_rr(code, opts->gen.cycles, opts->gen.limit, SZ_D); |
2257 uint8_t * jmp_off = code->cur+1; | 2261 uint8_t * jmp_off = code->cur+1; |
2258 jcc(code, CC_NC, code->cur + 7); | 2262 jcc(code, CC_NC, code->cur + 7); |
2259 pop_r(code, opts->gen.scratch1); | 2263 pop_r(code, opts->gen.scratch1); |
2260 add_ir(code, check_int_size - (code->cur-native), opts->gen.scratch1, SZ_Q); | 2264 add_ir(code, check_int_size - (tmp_code.cur-native), opts->gen.scratch1, SZ_Q); |
2261 push_r(code, opts->gen.scratch1); | 2265 push_r(code, opts->gen.scratch1); |
2262 jmp(code, opts->gen.handle_cycle_limit_int); | 2266 jmp(code, opts->gen.handle_cycle_limit_int); |
2263 *jmp_off = code->cur - (jmp_off+1); | 2267 *jmp_off = code->cur - (jmp_off+1); |
2264 //jump back to body of translated instruction | 2268 //jump back to body of translated instruction |
2265 pop_r(code, opts->gen.scratch1); | 2269 pop_r(code, opts->gen.scratch1); |
2266 add_ir(code, check_int_size - (code->cur-native), opts->gen.scratch1, SZ_Q); | 2270 add_ir(code, check_int_size - (tmp_code.cur-native), opts->gen.scratch1, SZ_Q); |
2267 jmp_r(code, opts->gen.scratch1); | 2271 jmp_r(code, opts->gen.scratch1); |
2268 } else { | 2272 } else { |
2269 call(&tmp_code, bp_stub); | 2273 call(&tmp_code, bp_stub); |
2270 } | 2274 } |
2271 } | 2275 } |