Mercurial > repos > blastem
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; |