Mercurial > repos > blastem
comparison z80_to_x86.c @ 283:61f5d88ea01a
Implement RETI and RETN (untested). Cleanup tests for "terminal" instructions.
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Sat, 04 May 2013 15:15:55 -0700 |
parents | 7b8a49220e3b |
children | ed7098f717d7 |
comparison
equal
deleted
inserted
replaced
282:7b8a49220e3b | 283:61f5d88ea01a |
---|---|
1370 dst = call(dst, (uint8_t *)z80_native_addr); | 1370 dst = call(dst, (uint8_t *)z80_native_addr); |
1371 dst = jmp_r(dst, SCRATCH1); | 1371 dst = jmp_r(dst, SCRATCH1); |
1372 *no_call_off = dst - (no_call_off+1); | 1372 *no_call_off = dst - (no_call_off+1); |
1373 break; | 1373 break; |
1374 } | 1374 } |
1375 /*case Z80_RETI: | 1375 case Z80_RETI: |
1376 case Z80_RETN:*/ | 1376 //For some systems, this may need a callback for signalling interrupt routine completion |
1377 dst = zcycles(dst, 8);//T States: 4, 4 | |
1378 dst = mov_rr(dst, opts->regs[Z80_SP], SCRATCH1, SZ_W); | |
1379 dst = call(dst, (uint8_t *)z80_read_word);//T STates: 3, 3 | |
1380 dst = add_ir(dst, 2, opts->regs[Z80_SP], SZ_W); | |
1381 dst = call(dst, (uint8_t *)z80_native_addr); | |
1382 dst = jmp_r(dst, SCRATCH1); | |
1383 break; | |
1384 case Z80_RETN: | |
1385 dst = zcycles(dst, 8);//T States: 4, 4 | |
1386 dst = mov_rdisp8r(dst, CONTEXT, offsetof(z80_context, iff2), SCRATCH2, SZ_B); | |
1387 dst = mov_rr(dst, opts->regs[Z80_SP], SCRATCH1, SZ_W); | |
1388 dst = mov_rrdisp8(dst, SCRATCH2, CONTEXT, offsetof(z80_context, iff1), SZ_B); | |
1389 dst = call(dst, (uint8_t *)z80_read_word);//T STates: 3, 3 | |
1390 dst = add_ir(dst, 2, opts->regs[Z80_SP], SZ_W); | |
1391 dst = call(dst, (uint8_t *)z80_native_addr); | |
1392 dst = jmp_r(dst, SCRATCH1); | |
1393 break; | |
1377 case Z80_RST: { | 1394 case Z80_RST: { |
1378 //RST is basically CALL to an address in page 0 | 1395 //RST is basically CALL to an address in page 0 |
1379 dst = zcycles(dst, 5);//T States: 5 | 1396 dst = zcycles(dst, 5);//T States: 5 |
1380 dst = sub_ir(dst, 2, opts->regs[Z80_SP], SZ_W); | 1397 dst = sub_ir(dst, 2, opts->regs[Z80_SP], SZ_W); |
1381 dst = mov_ir(dst, address + 3, SCRATCH1, SZ_W); | 1398 dst = mov_ir(dst, address + 3, SCRATCH1, SZ_W); |
1411 } | 1428 } |
1412 } | 1429 } |
1413 return dst; | 1430 return dst; |
1414 } | 1431 } |
1415 | 1432 |
1433 uint8_t z80_is_terminal(z80inst * inst) | |
1434 { | |
1435 return inst->op == Z80_RET || inst->op == Z80_RETI || inst->op == Z80_RETN || inst->op == Z80_JP | |
1436 || inst->op == Z80_JR || inst->op == Z80_HALT || (inst->op == Z80_NOP && inst->immed == 42); | |
1437 } | |
1438 | |
1416 uint8_t * z80_get_native_address(z80_context * context, uint32_t address) | 1439 uint8_t * z80_get_native_address(z80_context * context, uint32_t address) |
1417 { | 1440 { |
1418 native_map_slot *map; | 1441 native_map_slot *map; |
1419 if (address < 0x4000) { | 1442 if (address < 0x4000) { |
1420 address &= 0x1FFF; | 1443 address &= 0x1FFF; |
1586 } | 1609 } |
1587 } | 1610 } |
1588 z80_map_native_address(context, address, dst, after-inst, ZMAX_NATIVE_SIZE); | 1611 z80_map_native_address(context, address, dst, after-inst, ZMAX_NATIVE_SIZE); |
1589 opts->cur_code = dst+ZMAX_NATIVE_SIZE; | 1612 opts->cur_code = dst+ZMAX_NATIVE_SIZE; |
1590 jmp(orig_start, dst); | 1613 jmp(orig_start, dst); |
1591 if(!(instbuf.op == Z80_RET || instbuf.op == Z80_RETI || instbuf.op == Z80_RETN || instbuf.op == Z80_JP || (instbuf.op == Z80_NOP && instbuf.immed == 42))) { | 1614 if (!z80_is_terminal(&instbuf)) { |
1592 jmp(native_end, z80_get_native_address_trans(context, address + after-inst)); | 1615 jmp(native_end, z80_get_native_address_trans(context, address + after-inst)); |
1593 } | 1616 } |
1594 z80_handle_deferred(context); | 1617 z80_handle_deferred(context); |
1595 return dst; | 1618 return dst; |
1596 } else { | 1619 } else { |
1597 dst = translate_z80inst(&instbuf, orig_start, context, address); | 1620 dst = translate_z80inst(&instbuf, orig_start, context, address); |
1598 if(!(instbuf.op == Z80_RET || instbuf.op == Z80_RETI || instbuf.op == Z80_RETN || instbuf.op == Z80_JP || (instbuf.op == Z80_NOP && instbuf.immed == 42))) { | 1621 if (!z80_is_terminal(&instbuf)) { |
1599 dst = jmp(dst, z80_get_native_address_trans(context, address + after-inst)); | 1622 dst = jmp(dst, z80_get_native_address_trans(context, address + after-inst)); |
1600 } | 1623 } |
1601 z80_handle_deferred(context); | 1624 z80_handle_deferred(context); |
1602 return orig_start; | 1625 return orig_start; |
1603 } | 1626 } |
1658 address &= 0xFFFF; | 1681 address &= 0xFFFF; |
1659 | 1682 |
1660 } else { | 1683 } else { |
1661 encoded = next; | 1684 encoded = next; |
1662 } | 1685 } |
1663 } while (!(inst.op == Z80_RET || inst.op == Z80_RETI || inst.op == Z80_RETN || inst.op == Z80_JP || (inst.op == Z80_NOP && inst.immed == 42))); | 1686 } while (!z80_is_terminal(&inst)); |
1664 process_deferred(&opts->deferred, context, (native_addr_func)z80_get_native_address); | 1687 process_deferred(&opts->deferred, context, (native_addr_func)z80_get_native_address); |
1665 if (opts->deferred) { | 1688 if (opts->deferred) { |
1666 address = opts->deferred->address; | 1689 address = opts->deferred->address; |
1667 dprintf("defferred address: %X\n", address); | 1690 dprintf("defferred address: %X\n", address); |
1668 if (address < 0x4000) { | 1691 if (address < 0x4000) { |