comparison z80_to_x86.c @ 1769:8fe162bdb038 mame_interp

Merge from default
author Michael Pavone <pavone@retrodev.com>
date Fri, 01 Mar 2019 14:17:29 -0800
parents 8a29c250f352
children 37afb9cf58be
comparison
equal deleted inserted replaced
1768:63256371046f 1769:8fe162bdb038
353 if (size != SZ_B) { 353 if (size != SZ_B) {
354 num_cycles += 2; 354 num_cycles += 2;
355 } 355 }
356 if (inst->reg == Z80_I || inst->ea_reg == Z80_I || inst->reg == Z80_R || inst->ea_reg == Z80_R) { 356 if (inst->reg == Z80_I || inst->ea_reg == Z80_I || inst->reg == Z80_R || inst->ea_reg == Z80_R) {
357 num_cycles += 1; 357 num_cycles += 1;
358 } else if (inst->reg == Z80_USE_IMMED) {
359 num_cycles += 3;
358 } 360 }
359 break; 361 break;
360 case Z80_IMMED: 362 case Z80_IMMED:
361 num_cycles += size == SZ_B ? 3 : 6; 363 num_cycles += size == SZ_B ? 3 : 6;
362 break; 364 break;
872 if (inst->addr_mode == Z80_IX_DISPLACE || inst->addr_mode == Z80_IY_DISPLACE) { 874 if (inst->addr_mode == Z80_IX_DISPLACE || inst->addr_mode == Z80_IY_DISPLACE) {
873 num_cycles += 8; 875 num_cycles += 8;
874 } else if(inst->addr_mode == Z80_IMMED) { 876 } else if(inst->addr_mode == Z80_IMMED) {
875 num_cycles += 3; 877 num_cycles += 3;
876 } else if(z80_size(inst) == SZ_W) { 878 } else if(z80_size(inst) == SZ_W) {
877 num_cycles += 4; 879 num_cycles += 7;
878 } 880 }
879 cycles(&opts->gen, num_cycles); 881 cycles(&opts->gen, num_cycles);
880 translate_z80_reg(inst, &dst_op, opts); 882 translate_z80_reg(inst, &dst_op, opts);
881 translate_z80_ea(inst, &src_op, opts, READ, DONT_MODIFY); 883 translate_z80_ea(inst, &src_op, opts, READ, DONT_MODIFY);
882 if (dst_op.mode == MODE_REG_DIRECT) { 884 if (dst_op.mode == MODE_REG_DIRECT) {
940 if (inst->addr_mode == Z80_IX_DISPLACE || inst->addr_mode == Z80_IY_DISPLACE) { 942 if (inst->addr_mode == Z80_IX_DISPLACE || inst->addr_mode == Z80_IY_DISPLACE) {
941 num_cycles += 8; 943 num_cycles += 8;
942 } else if(inst->addr_mode == Z80_IMMED) { 944 } else if(inst->addr_mode == Z80_IMMED) {
943 num_cycles += 3; 945 num_cycles += 3;
944 } else if(z80_size(inst) == SZ_W) { 946 } else if(z80_size(inst) == SZ_W) {
945 num_cycles += 4; 947 num_cycles += 7;
946 } 948 }
947 cycles(&opts->gen, num_cycles); 949 cycles(&opts->gen, num_cycles);
948 translate_z80_reg(inst, &dst_op, opts); 950 translate_z80_reg(inst, &dst_op, opts);
949 translate_z80_ea(inst, &src_op, opts, READ, DONT_MODIFY); 951 translate_z80_ea(inst, &src_op, opts, READ, DONT_MODIFY);
950 if (dst_op.mode == MODE_REG_DIRECT) { 952 if (dst_op.mode == MODE_REG_DIRECT) {
1071 if (inst->addr_mode == Z80_IX_DISPLACE || inst->addr_mode == Z80_IY_DISPLACE) { 1073 if (inst->addr_mode == Z80_IX_DISPLACE || inst->addr_mode == Z80_IY_DISPLACE) {
1072 num_cycles += 8; 1074 num_cycles += 8;
1073 } else if(inst->addr_mode == Z80_IMMED) { 1075 } else if(inst->addr_mode == Z80_IMMED) {
1074 num_cycles += 3; 1076 num_cycles += 3;
1075 } else if(z80_size(inst) == SZ_W) { 1077 } else if(z80_size(inst) == SZ_W) {
1076 num_cycles += 4; 1078 num_cycles += 7;
1077 } 1079 }
1078 cycles(&opts->gen, num_cycles); 1080 cycles(&opts->gen, num_cycles);
1079 translate_z80_reg(inst, &dst_op, opts); 1081 translate_z80_reg(inst, &dst_op, opts);
1080 translate_z80_ea(inst, &src_op, opts, READ, DONT_MODIFY); 1082 translate_z80_ea(inst, &src_op, opts, READ, DONT_MODIFY);
1081 if (dst_op.mode == MODE_REG_DIRECT) { 1083 if (dst_op.mode == MODE_REG_DIRECT) {
1259 break; 1261 break;
1260 case Z80_INC: 1262 case Z80_INC:
1261 case Z80_DEC: 1263 case Z80_DEC:
1262 if(z80_size(inst) == SZ_W) { 1264 if(z80_size(inst) == SZ_W) {
1263 num_cycles += 2; 1265 num_cycles += 2;
1266 } else if (inst->addr_mode == Z80_REG_INDIRECT) {
1267 num_cycles += 1;
1268 } else if (inst->addr_mode == Z80_IX_DISPLACE || inst->addr_mode == Z80_IY_DISPLACE) {
1269 num_cycles += 9;
1264 } 1270 }
1265 cycles(&opts->gen, num_cycles); 1271 cycles(&opts->gen, num_cycles);
1266 translate_z80_reg(inst, &dst_op, opts); 1272 translate_z80_reg(inst, &dst_op, opts);
1267 if (dst_op.mode == MODE_UNUSED) { 1273 if (dst_op.mode == MODE_UNUSED) {
1268 translate_z80_ea(inst, &dst_op, opts, READ, MODIFY); 1274 translate_z80_ea(inst, &dst_op, opts, READ, MODIFY);
1851 ror_ir(code, 8, opts->gen.scratch1, SZ_W); 1857 ror_ir(code, 8, opts->gen.scratch1, SZ_W);
1852 call(code, opts->write_8); 1858 call(code, opts->write_8);
1853 break; 1859 break;
1854 case Z80_BIT: { 1860 case Z80_BIT: {
1855 if (inst->addr_mode == Z80_IX_DISPLACE || inst->addr_mode == Z80_IY_DISPLACE) { 1861 if (inst->addr_mode == Z80_IX_DISPLACE || inst->addr_mode == Z80_IY_DISPLACE) {
1856 num_cycles += 8; 1862 num_cycles += 4;
1857 } 1863 }
1858 cycles(&opts->gen, num_cycles); 1864 cycles(&opts->gen, num_cycles);
1859 uint8_t bit; 1865 uint8_t bit;
1860 if ((inst->addr_mode & 0x1F) == Z80_REG && opts->regs[inst->ea_reg] >= AH && opts->regs[inst->ea_reg] <= BH) { 1866 if ((inst->addr_mode & 0x1F) == Z80_REG && opts->regs[inst->ea_reg] >= AH && opts->regs[inst->ea_reg] <= BH) {
1861 src_op.base = opts->regs[z80_word_reg(inst->ea_reg)]; 1867 src_op.base = opts->regs[z80_word_reg(inst->ea_reg)];
1912 } 1918 }
1913 break; 1919 break;
1914 } 1920 }
1915 case Z80_SET: { 1921 case Z80_SET: {
1916 if (inst->addr_mode == Z80_IX_DISPLACE || inst->addr_mode == Z80_IY_DISPLACE) { 1922 if (inst->addr_mode == Z80_IX_DISPLACE || inst->addr_mode == Z80_IY_DISPLACE) {
1917 num_cycles += 8; 1923 num_cycles += 4;
1918 } 1924 }
1919 cycles(&opts->gen, num_cycles); 1925 cycles(&opts->gen, num_cycles);
1920 uint8_t bit; 1926 uint8_t bit;
1921 if ((inst->addr_mode & 0x1F) == Z80_REG && opts->regs[inst->ea_reg] >= AH && opts->regs[inst->ea_reg] <= BH) { 1927 if ((inst->addr_mode & 0x1F) == Z80_REG && opts->regs[inst->ea_reg] >= AH && opts->regs[inst->ea_reg] <= BH) {
1922 src_op.base = opts->regs[z80_word_reg(inst->ea_reg)]; 1928 src_op.base = opts->regs[z80_word_reg(inst->ea_reg)];
1981 } 1987 }
1982 break; 1988 break;
1983 } 1989 }
1984 case Z80_RES: { 1990 case Z80_RES: {
1985 if (inst->addr_mode == Z80_IX_DISPLACE || inst->addr_mode == Z80_IY_DISPLACE) { 1991 if (inst->addr_mode == Z80_IX_DISPLACE || inst->addr_mode == Z80_IY_DISPLACE) {
1986 num_cycles += 8; 1992 num_cycles += 4;
1987 } 1993 }
1988 cycles(&opts->gen, num_cycles); 1994 cycles(&opts->gen, num_cycles);
1989 uint8_t bit; 1995 uint8_t bit;
1990 if ((inst->addr_mode & 0x1F) == Z80_REG && opts->regs[inst->ea_reg] >= AH && opts->regs[inst->ea_reg] <= BH) { 1996 if ((inst->addr_mode & 0x1F) == Z80_REG && opts->regs[inst->ea_reg] >= AH && opts->regs[inst->ea_reg] <= BH) {
1991 src_op.base = opts->regs[z80_word_reg(inst->ea_reg)]; 1997 src_op.base = opts->regs[z80_word_reg(inst->ea_reg)];
2591 jmp(code, start); 2597 jmp(code, start);
2592 *done = code->cur - (done + 1); 2598 *done = code->cur - (done + 1);
2593 break; 2599 break;
2594 } 2600 }
2595 case Z80_OUT: 2601 case Z80_OUT:
2596 if (inst->reg == Z80_A) { 2602 if (inst->addr_mode == Z80_IMMED_INDIRECT) {
2597 num_cycles += 3; 2603 num_cycles += 3;
2598 } 2604 }
2599 cycles(&opts->gen, num_cycles);//T States: 4 3/4 2605 cycles(&opts->gen, num_cycles);//T States: 4 3/4
2600 if ((inst->addr_mode & 0x1F) == Z80_IMMED_INDIRECT) { 2606 if ((inst->addr_mode & 0x1F) == Z80_IMMED_INDIRECT) {
2601 mov_ir(code, inst->immed, opts->gen.scratch2, SZ_B); 2607 mov_ir(code, inst->immed, opts->gen.scratch2, SZ_B);
2656 xor_rdispr(code, opts->gen.context_reg, zr_off(Z80_B), opts->gen.scratch1, SZ_B); 2662 xor_rdispr(code, opts->gen.context_reg, zr_off(Z80_B), opts->gen.scratch1, SZ_B);
2657 } 2663 }
2658 setcc_rdisp(code, CC_P, opts->gen.context_reg, zf_off(ZF_PV)); 2664 setcc_rdisp(code, CC_P, opts->gen.context_reg, zf_off(ZF_PV));
2659 break; 2665 break;
2660 case Z80_OTIR: { 2666 case Z80_OTIR: {
2661 code_ptr start = code->cur;
2662 cycles(&opts->gen, num_cycles + 1);//T States: 4, 5 2667 cycles(&opts->gen, num_cycles + 1);//T States: 4, 5
2663 //read from (HL) 2668 //read from (HL)
2664 zreg_to_native(opts, Z80_HL, opts->gen.scratch1); 2669 zreg_to_native(opts, Z80_HL, opts->gen.scratch1);
2665 call(code, opts->read_8);//T states 3 2670 call(code, opts->read_8);//T states 3
2666 //undocumented N flag behavior 2671 //undocumented N flag behavior
2756 xor_rdispr(code, opts->gen.context_reg, zr_off(Z80_B), opts->gen.scratch1, SZ_B); 2761 xor_rdispr(code, opts->gen.context_reg, zr_off(Z80_B), opts->gen.scratch1, SZ_B);
2757 } 2762 }
2758 setcc_rdisp(code, CC_P, opts->gen.context_reg, zf_off(ZF_PV)); 2763 setcc_rdisp(code, CC_P, opts->gen.context_reg, zf_off(ZF_PV));
2759 break; 2764 break;
2760 case Z80_OTDR: { 2765 case Z80_OTDR: {
2761 code_ptr start = code->cur;
2762 cycles(&opts->gen, num_cycles + 1);//T States: 4, 5 2766 cycles(&opts->gen, num_cycles + 1);//T States: 4, 5
2763 //read from (HL) 2767 //read from (HL)
2764 zreg_to_native(opts, Z80_HL, opts->gen.scratch1); 2768 zreg_to_native(opts, Z80_HL, opts->gen.scratch1);
2765 call(code, opts->read_8);//T states 3 2769 call(code, opts->read_8);//T states 3
2766 //undocumented N flag behavior 2770 //undocumented N flag behavior
3418 cmp_irdisp(code, 0, options->gen.context_reg, offsetof(z80_context, int_is_nmi), SZ_B); 3422 cmp_irdisp(code, 0, options->gen.context_reg, offsetof(z80_context, int_is_nmi), SZ_B);
3419 code_ptr is_nmi = code->cur + 1; 3423 code_ptr is_nmi = code->cur + 1;
3420 jcc(code, CC_NZ, is_nmi); 3424 jcc(code, CC_NZ, is_nmi);
3421 mov_irdisp(code, 0, options->gen.context_reg, offsetof(z80_context, iff1), SZ_B); 3425 mov_irdisp(code, 0, options->gen.context_reg, offsetof(z80_context, iff1), SZ_B);
3422 mov_irdisp(code, 0, options->gen.context_reg, offsetof(z80_context, iff2), SZ_B); 3426 mov_irdisp(code, 0, options->gen.context_reg, offsetof(z80_context, iff2), SZ_B);
3427 cycles(&options->gen, 6); //interupt ack cycle
3423 code_ptr after_int_disable = code->cur + 1; 3428 code_ptr after_int_disable = code->cur + 1;
3424 jmp(code, after_int_disable); 3429 jmp(code, after_int_disable);
3425 *is_nmi = code->cur - (is_nmi + 1); 3430 *is_nmi = code->cur - (is_nmi + 1);
3426 mov_rdispr(code, options->gen.context_reg, offsetof(z80_context, iff1), options->gen.scratch2, SZ_B); 3431 mov_rdispr(code, options->gen.context_reg, offsetof(z80_context, iff1), options->gen.scratch2, SZ_B);
3427 mov_irdisp(code, 0, options->gen.context_reg, offsetof(z80_context, iff1), SZ_B); 3432 mov_irdisp(code, 0, options->gen.context_reg, offsetof(z80_context, iff1), SZ_B);
3428 mov_rrdisp(code, options->gen.scratch2, options->gen.context_reg, offsetof(z80_context, iff2), SZ_B); 3433 mov_rrdisp(code, options->gen.scratch2, options->gen.context_reg, offsetof(z80_context, iff2), SZ_B);
3434 cycles(&options->gen, 5); //NMI processing cycles
3429 *after_int_disable = code->cur - (after_int_disable + 1); 3435 *after_int_disable = code->cur - (after_int_disable + 1);
3430 cycles(&options->gen, 7);
3431 //save return address (in scratch1) to Z80 stack 3436 //save return address (in scratch1) to Z80 stack
3432 sub_ir(code, 2, options->regs[Z80_SP], SZ_W); 3437 sub_ir(code, 2, options->regs[Z80_SP], SZ_W);
3433 mov_rr(code, options->regs[Z80_SP], options->gen.scratch2, SZ_W); 3438 mov_rr(code, options->regs[Z80_SP], options->gen.scratch2, SZ_W);
3434 //we need to do check_cycles and cycles outside of the write_8 call 3439 //we need to do check_cycles and cycles outside of the write_8 call
3435 //so that the stack has the correct depth if we need to return to C 3440 //so that the stack has the correct depth if we need to return to C
3451 //dispose of return address as we'll be jumping somewhere else 3456 //dispose of return address as we'll be jumping somewhere else
3452 add_ir(code, 16, RSP, SZ_PTR); 3457 add_ir(code, 16, RSP, SZ_PTR);
3453 cmp_irdisp(code, 0, options->gen.context_reg, offsetof(z80_context, int_is_nmi), SZ_B); 3458 cmp_irdisp(code, 0, options->gen.context_reg, offsetof(z80_context, int_is_nmi), SZ_B);
3454 is_nmi = code->cur + 1; 3459 is_nmi = code->cur + 1;
3455 jcc(code, CC_NZ, is_nmi); 3460 jcc(code, CC_NZ, is_nmi);
3456 cycles(&options->gen, 6); //interupt ack cycle
3457 //TODO: Support interrupt mode 0, not needed for Genesis sit it seems to read $FF during intack 3461 //TODO: Support interrupt mode 0, not needed for Genesis sit it seems to read $FF during intack
3458 //which is conveniently rst $38, i.e. the same thing that im 1 does 3462 //which is conveniently rst $38, i.e. the same thing that im 1 does
3459 //check interrupt mode 3463 //check interrupt mode
3460 cmp_irdisp(code, 2, options->gen.context_reg, offsetof(z80_context, im), SZ_B); 3464 cmp_irdisp(code, 2, options->gen.context_reg, offsetof(z80_context, im), SZ_B);
3461 code_ptr im2 = code->cur + 1; 3465 code_ptr im2 = code->cur + 1;
3462 jcc(code, CC_Z, im2); 3466 jcc(code, CC_Z, im2);
3463 mov_ir(code, 0x38, options->gen.scratch1, SZ_W); 3467 mov_ir(code, 0x38, options->gen.scratch1, SZ_W);
3468 cycles(&options->gen, 1); //total time for mode 0/1 is 13 t-states
3464 code_ptr after_int_dest = code->cur + 1; 3469 code_ptr after_int_dest = code->cur + 1;
3465 jmp(code, after_int_dest); 3470 jmp(code, after_int_dest);
3466 *im2 = code->cur - (im2 + 1); 3471 *im2 = code->cur - (im2 + 1);
3467 //read vector address from I << 8 | vector 3472 //read vector address from I << 8 | vector
3468 mov_rdispr(code, options->gen.context_reg, offsetof(z80_context, regs) + Z80_I, options->gen.scratch1, SZ_B); 3473 mov_rdispr(code, options->gen.context_reg, offsetof(z80_context, regs) + Z80_I, options->gen.scratch1, SZ_B);
3499 code->stack_off = tmp_stack_off; 3504 code->stack_off = tmp_stack_off;
3500 3505
3501 //HACK 3506 //HACK
3502 options->gen.address_size = SZ_D; 3507 options->gen.address_size = SZ_D;
3503 options->gen.address_mask = io_address_mask; 3508 options->gen.address_mask = io_address_mask;
3509 options->gen.bus_cycles = 4;
3504 options->read_io = gen_mem_fun(&options->gen, io_chunks, num_io_chunks, READ_8, NULL); 3510 options->read_io = gen_mem_fun(&options->gen, io_chunks, num_io_chunks, READ_8, NULL);
3505 options->write_io = gen_mem_fun(&options->gen, io_chunks, num_io_chunks, WRITE_8, NULL); 3511 options->write_io = gen_mem_fun(&options->gen, io_chunks, num_io_chunks, WRITE_8, NULL);
3506 options->gen.address_size = SZ_W; 3512 options->gen.address_size = SZ_W;
3507 options->gen.address_mask = 0xFFFF; 3513 options->gen.address_mask = 0xFFFF;
3514 options->gen.bus_cycles = 3;
3508 3515
3509 options->read_16 = code->cur; 3516 options->read_16 = code->cur;
3510 cycles(&options->gen, 3); 3517 cycles(&options->gen, 3);
3511 check_cycles(&options->gen); 3518 check_cycles(&options->gen);
3512 //TODO: figure out how to handle the extra wait state for word reads to bank area 3519 //TODO: figure out how to handle the extra wait state for word reads to bank area