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) {