comparison z80_to_x86.c @ 239:a5bea9711a46

Implement BIT and DJNZ (tested). Fix register mapping for IYL.
author Mike Pavone <pavone@retrodev.com>
date Fri, 26 Apr 2013 22:27:17 -0700
parents 827ebce557bf
children 2586d49ddd46
comparison
equal deleted inserted replaced
238:827ebce557bf 239:a5bea9711a46
528 case Z80_SLA: 528 case Z80_SLA:
529 case Z80_SRA: 529 case Z80_SRA:
530 case Z80_SLL: 530 case Z80_SLL:
531 case Z80_SRL: 531 case Z80_SRL:
532 case Z80_RLD: 532 case Z80_RLD:
533 case Z80_RRD: 533 case Z80_RRD:*/
534 case Z80_BIT: 534 case Z80_BIT:
535 case Z80_SET: 535 cycles = (inst->addr_mode == Z80_IX_DISPLACE || inst->addr_mode == Z80_IY_DISPLACE) ? 8 : 16;
536 case Z80_RES:*/ 536 dst = zcycles(dst, cycles);
537 dst = translate_z80_ea(inst, &src_op, dst, opts, READ, DONT_MODIFY);
538 if (inst->addr_mode != Z80_REG) {
539 //Reads normally take 3 cycles, but the read at the end of a bit instruction takes 4
540 dst = zcycles(dst, 1);
541 }
542 dst = bt_ir(dst, inst->immed, src_op.base, SZ_B);
543 dst = setcc_rdisp8(dst, CC_C, CONTEXT, zf_off(ZF_Z));
544 break;
545 //case Z80_SET:
546 //case Z80_RES:
537 case Z80_JP: { 547 case Z80_JP: {
538 cycles = 4; 548 cycles = 4;
539 if (inst->addr_mode != MODE_REG_INDIRECT) { 549 if (inst->addr_mode != Z80_REG) {
540 cycles += 6; 550 cycles += 6;
541 } else if(inst->ea_reg == Z80_IX || inst->ea_reg == Z80_IY) { 551 } else if(inst->ea_reg == Z80_IX || inst->ea_reg == Z80_IY) {
542 cycles += 4; 552 cycles += 4;
543 } 553 }
544 dst = zcycles(dst, cycles); 554 dst = zcycles(dst, cycles);
545 if (inst->addr_mode != MODE_REG_INDIRECT && inst->immed < 0x4000) { 555 if (inst->addr_mode != Z80_REG_INDIRECT && inst->immed < 0x4000) {
546 uint8_t * call_dst = z80_get_native_address(context, inst->immed); 556 uint8_t * call_dst = z80_get_native_address(context, inst->immed);
547 if (!call_dst) { 557 if (!call_dst) {
548 opts->deferred = defer_address(opts->deferred, inst->immed, dst + 1); 558 opts->deferred = defer_address(opts->deferred, inst->immed, dst + 1);
549 //fake address to force large displacement 559 //fake address to force large displacement
550 call_dst = dst + 256; 560 call_dst = dst + 256;
551 } 561 }
552 dst = jmp(dst, call_dst); 562 dst = jmp(dst, call_dst);
553 } else { 563 } else {
554 if (inst->addr_mode == MODE_REG_INDIRECT) { 564 if (inst->addr_mode == Z80_REG_INDIRECT) {
555 dst = mov_rr(dst, opts->regs[inst->ea_reg], SCRATCH1, SZ_W); 565 dst = mov_rr(dst, opts->regs[inst->ea_reg], SCRATCH1, SZ_W);
556 } else { 566 } else {
557 dst = mov_ir(dst, inst->immed, SCRATCH1, SZ_W); 567 dst = mov_ir(dst, inst->immed, SCRATCH1, SZ_W);
558 } 568 }
559 dst = call(dst, (uint8_t *)z80_native_addr); 569 dst = call(dst, (uint8_t *)z80_native_addr);
658 dst = jmp_r(dst, SCRATCH1); 668 dst = jmp_r(dst, SCRATCH1);
659 } 669 }
660 *no_jump_off = dst - (no_jump_off+1); 670 *no_jump_off = dst - (no_jump_off+1);
661 break; 671 break;
662 } 672 }
663 //case Z80_DJNZ:*/ 673 case Z80_DJNZ:
674 dst = zcycles(dst, 8);//T States: 5,3
675 dst = sub_ir(dst, 1, opts->regs[Z80_B], SZ_B);
676 uint8_t *no_jump_off = dst+1;
677 dst = jcc(dst, CC_Z, dst+2);
678 dst = zcycles(dst, 5);//T States: 5
679 uint16_t dest_addr = address + inst->immed + 2;
680 if (dest_addr < 0x4000) {
681 uint8_t * call_dst = z80_get_native_address(context, dest_addr);
682 if (!call_dst) {
683 opts->deferred = defer_address(opts->deferred, dest_addr, dst + 1);
684 //fake address to force large displacement
685 call_dst = dst + 256;
686 }
687 dst = jmp(dst, call_dst);
688 } else {
689 dst = mov_ir(dst, dest_addr, SCRATCH1, SZ_W);
690 dst = call(dst, (uint8_t *)z80_native_addr);
691 dst = jmp_r(dst, SCRATCH1);
692 }
693 *no_jump_off = dst - (no_jump_off+1);
694 break;
664 case Z80_CALL: { 695 case Z80_CALL: {
665 dst = zcycles(dst, 11);//T States: 4,3,4 696 dst = zcycles(dst, 11);//T States: 4,3,4
666 dst = sub_ir(dst, 2, opts->regs[Z80_SP], SZ_W); 697 dst = sub_ir(dst, 2, opts->regs[Z80_SP], SZ_W);
667 dst = mov_ir(dst, address + 3, SCRATCH2, SZ_W); 698 dst = mov_ir(dst, address + 3, SCRATCH2, SZ_W);
668 dst = mov_rr(dst, opts->regs[Z80_SP], SCRATCH1, SZ_W); 699 dst = mov_rr(dst, opts->regs[Z80_SP], SCRATCH1, SZ_W);
890 options->regs[Z80_H] = AH; 921 options->regs[Z80_H] = AH;
891 options->regs[Z80_L] = RAX; 922 options->regs[Z80_L] = RAX;
892 options->regs[Z80_IXH] = DH; 923 options->regs[Z80_IXH] = DH;
893 options->regs[Z80_IXL] = RDX; 924 options->regs[Z80_IXL] = RDX;
894 options->regs[Z80_IYH] = -1; 925 options->regs[Z80_IYH] = -1;
895 options->regs[Z80_IYL] = -1; 926 options->regs[Z80_IYL] = R8;
896 options->regs[Z80_I] = -1; 927 options->regs[Z80_I] = -1;
897 options->regs[Z80_R] = -1; 928 options->regs[Z80_R] = -1;
898 options->regs[Z80_A] = R10; 929 options->regs[Z80_A] = R10;
899 options->regs[Z80_BC] = RBX; 930 options->regs[Z80_BC] = RBX;
900 options->regs[Z80_DE] = RCX; 931 options->regs[Z80_DE] = RCX;