# HG changeset patch # User Michael Pavone # Date 1470070090 25200 # Node ID 56713dac6a6984140e949f1e7348669a607beefe # Parent 8da9677797107cc18b62cc57ec6621a01c2f2d38 Implement INI diff -r 8da967779710 -r 56713dac6a69 z80_to_x86.c --- a/z80_to_x86.c Sun Jul 31 15:20:00 2016 -0700 +++ b/z80_to_x86.c Mon Aug 01 09:48:10 2016 -0700 @@ -2336,8 +2336,64 @@ } z80_save_reg(inst, opts); break; - /*case Z80_INI: - case Z80_INIR: + case Z80_INI: + cycles(&opts->gen, num_cycles + 1);//T States: 4, 5 + //read from IO (C) + zreg_to_native(opts, Z80_BC, opts->gen.scratch1); + call(code, opts->read_io);//T states 3 + + //undocumented N flag behavior + //flag set on bit 7 of value written + bt_ir(code, 7, opts->gen.scratch1, SZ_B); + setcc_rdisp(code, CC_C, opts->gen.context_reg, zf_off(ZF_N)); + //save value to be written for flag calculation, as the write func does not + //guarantee that it's preserved across the call + mov_rrdisp(code, opts->gen.scratch1, opts->gen.context_reg, offsetof(z80_context, scratch1), SZ_B); + + //write to (HL) + zreg_to_native(opts, Z80_HL, opts->gen.scratch2); + call(code, opts->write_8);//T states 4 + cycles(&opts->gen, 1); + + //increment HL + if (opts->regs[Z80_HL] >= 0) { + add_ir(code, 1, opts->regs[Z80_HL], SZ_W); + } else { + add_irdisp(code, 1, opts->gen.context_reg, zr_off(Z80_HL), SZ_B); + } + mov_rdispr(code, opts->gen.context_reg, offsetof(z80_context, scratch1), opts->gen.scratch1, SZ_B); + if (opts->regs[Z80_C] >= 0) { + add_rr(code, opts->regs[Z80_C], opts->gen.scratch1, SZ_B); + } else { + add_rdispr(code, opts->gen.context_reg, zr_off(Z80_C), opts->gen.scratch1, SZ_B); + } + add_ir(code, 1, opts->gen.scratch1, SZ_B); + //undocumented C and H flag behavior + setcc_rdisp(code, CC_C, opts->gen.context_reg, zf_off(ZF_C)); + setcc_rdisp(code, CC_C, opts->gen.context_reg, zf_off(ZF_H)); + //decrement B + if (opts->regs[Z80_B] >= 0) { + sub_ir(code, 1, opts->regs[Z80_B], SZ_B); + mov_rrdisp(code, opts->regs[Z80_B], opts->gen.context_reg, zf_off(ZF_XY), SZ_B); + } else { + sub_irdisp(code, 1, opts->gen.context_reg, zr_off(Z80_B), SZ_B); + } + //undocumented Z and S flag behavior, set based on decrement of B + setcc_rdisp(code, CC_Z, opts->gen.context_reg, zf_off(ZF_Z)); + setcc_rdisp(code, CC_S, opts->gen.context_reg, zf_off(ZF_S)); + //crazy undocumented P/V flag behavior + and_ir(code, 7, opts->gen.scratch1, SZ_B); + if (opts->regs[Z80_B] >= 0) { + //deal with silly x86-64 restrictions on *H registers + ror_ir(code, 8, opts->regs[Z80_BC], SZ_W); + xor_rr(code, opts->regs[Z80_C], opts->gen.scratch1, SZ_B); + ror_ir(code, 8, opts->regs[Z80_BC], SZ_W); + } else { + xor_rdispr(code, opts->gen.context_reg, zr_off(Z80_B), opts->gen.scratch1, SZ_B); + } + setcc_rdisp(code, CC_P, opts->gen.context_reg, zf_off(ZF_PV)); + break; + /*case Z80_INIR: case Z80_IND: case Z80_INDR:*/ case Z80_OUT: diff -r 8da967779710 -r 56713dac6a69 ztestrun.c --- a/ztestrun.c Sun Jul 31 15:20:00 2016 -0700 +++ b/ztestrun.c Mon Aug 01 09:48:10 2016 -0700 @@ -38,6 +38,10 @@ { 0x4000, 0x10000, 0xFFFF, 0, 0, NULL, NULL, NULL, z80_unmapped_read, z80_unmapped_write} }; +const memmap_chunk port_map[] = { + { 0x0000, 0x100, 0xFF, 0, 0, NULL, NULL, NULL, z80_unmapped_read, z80_unmapped_write} +}; + void z80_next_int_pulse(z80_context * context) { context->int_pulse_start = context->int_pulse_end = CYCLE_NEVER; @@ -85,7 +89,7 @@ exit(1); } fclose(f); - init_z80_opts(&opts, z80_map, 2, NULL, 0, 1); + init_z80_opts(&opts, z80_map, 2, port_map, 1, 1); init_z80_context(&context, &opts); //Z80 RAM context.mem_pointers[0] = z80_ram;