comparison z80_to_x86.c @ 594:086de8692932

Add in missing generated Z80 helper functions. Fix a small bug in Z80_HALT. Fix generation of save and load context for Z80
author Michael Pavone <pavone@retrodev.com>
date Fri, 26 Dec 2014 12:34:41 -0800
parents 5ef3fe516da9
children 8d6ae5b3b87b
comparison
equal deleted inserted replaced
593:5ef3fe516da9 594:086de8692932
868 sub_rr(code, opts->gen.cycles, opts->gen.scratch2, SZ_D); 868 sub_rr(code, opts->gen.cycles, opts->gen.scratch2, SZ_D);
869 and_ir(code, 0xFFFFFFFC, opts->gen.scratch2, SZ_D); 869 and_ir(code, 0xFFFFFFFC, opts->gen.scratch2, SZ_D);
870 add_rr(code, opts->gen.scratch2, opts->gen.cycles, SZ_D); 870 add_rr(code, opts->gen.scratch2, opts->gen.cycles, SZ_D);
871 cmp_rr(code, opts->gen.limit, opts->gen.cycles, SZ_D); 871 cmp_rr(code, opts->gen.limit, opts->gen.cycles, SZ_D);
872 code_ptr skip_last = code->cur+1; 872 code_ptr skip_last = code->cur+1;
873 jcc(code, CC_B, opts->gen.handle_cycle_limit_int); 873 jcc(code, CC_NB, code->cur+2);
874 cycles(&opts->gen, 4); 874 cycles(&opts->gen, 4);
875 *skip_last = code->cur - (skip_last+1); 875 *skip_last = code->cur - (skip_last+1);
876 call(code, opts->gen.handle_cycle_limit_int); 876 call(code, opts->gen.handle_cycle_limit_int);
877 jmp(code, call_inst); 877 jmp(code, call_inst);
878 break; 878 break;
1951 for (int i = 0; i <= Z80_A; i++) 1951 for (int i = 0; i <= Z80_A; i++)
1952 { 1952 {
1953 int reg; 1953 int reg;
1954 uint8_t size; 1954 uint8_t size;
1955 if (i < Z80_I) { 1955 if (i < Z80_I) {
1956 reg = i /2 + Z80_BC; 1956 reg = i /2 + Z80_BC + (i > Z80_H ? 2 : 0);
1957 size = SZ_W; 1957 size = SZ_W;
1958 i++;
1959
1960 } else { 1958 } else {
1961 reg = i; 1959 reg = i;
1962 size = SZ_B; 1960 size = SZ_B;
1963 } 1961 }
1964 if (options->regs[reg] >= 0) { 1962 if (options->regs[reg] >= 0) {
1965 mov_rrdisp(code, options->regs[reg], options->gen.context_reg, offsetof(z80_context, regs) + i, size); 1963 mov_rrdisp(code, options->regs[reg], options->gen.context_reg, offsetof(z80_context, regs) + i, size);
1964 }
1965 if (size == SZ_W) {
1966 i++;
1966 } 1967 }
1967 } 1968 }
1968 if (options->regs[Z80_SP] >= 0) { 1969 if (options->regs[Z80_SP] >= 0) {
1969 mov_rrdisp(code, options->regs[Z80_SP], options->gen.context_reg, offsetof(z80_context, sp), SZ_W); 1970 mov_rrdisp(code, options->regs[Z80_SP], options->gen.context_reg, offsetof(z80_context, sp), SZ_W);
1970 } 1971 }
1981 for (int i = 0; i <= Z80_A; i++) 1982 for (int i = 0; i <= Z80_A; i++)
1982 { 1983 {
1983 int reg; 1984 int reg;
1984 uint8_t size; 1985 uint8_t size;
1985 if (i < Z80_I) { 1986 if (i < Z80_I) {
1986 int reg = i /2 + Z80_BC; 1987 reg = i /2 + Z80_BC + (i > Z80_H ? 2 : 0);
1987 size = SZ_W; 1988 size = SZ_W;
1988
1989 } else { 1989 } else {
1990 reg = i; 1990 reg = i;
1991 size = SZ_B; 1991 size = SZ_B;
1992 } 1992 }
1993 if (options->regs[reg] >= 0) { 1993 if (options->regs[reg] >= 0) {
1994 mov_rdispr(code, options->gen.context_reg, offsetof(z80_context, regs) + i, options->regs[reg], size); 1994 mov_rdispr(code, options->gen.context_reg, offsetof(z80_context, regs) + i, options->regs[reg], size);
1995 }
1996 if (size == SZ_W) {
1997 i++;
1995 } 1998 }
1996 } 1999 }
1997 if (options->regs[Z80_SP] >= 0) { 2000 if (options->regs[Z80_SP] >= 0) {
1998 mov_rdispr(code, options->gen.context_reg, offsetof(z80_context, sp), options->regs[Z80_SP], SZ_W); 2001 mov_rdispr(code, options->gen.context_reg, offsetof(z80_context, sp), options->regs[Z80_SP], SZ_W);
1999 } 2002 }
2033 pop_r(code, RBP); 2036 pop_r(code, RBP);
2034 pop_r(code, RBX); 2037 pop_r(code, RBX);
2035 *no_sync = code->cur - no_sync; 2038 *no_sync = code->cur - no_sync;
2036 //return to caller of z80_run 2039 //return to caller of z80_run
2037 retn(code); 2040 retn(code);
2038 2041
2039 options->read_8 = gen_mem_fun(&options->gen, chunks, num_chunks, READ_8, NULL); 2042 options->gen.handle_code_write = (code_ptr)z80_handle_code_write;
2043
2044 options->read_8 = gen_mem_fun(&options->gen, chunks, num_chunks, READ_8, &options->read_8_noinc);
2040 options->write_8 = gen_mem_fun(&options->gen, chunks, num_chunks, WRITE_8, &options->write_8_noinc); 2045 options->write_8 = gen_mem_fun(&options->gen, chunks, num_chunks, WRITE_8, &options->write_8_noinc);
2041 2046
2042 options->gen.handle_cycle_limit_int = code->cur; 2047 options->gen.handle_cycle_limit_int = code->cur;
2043 cmp_rdispr(code, options->gen.context_reg, offsetof(z80_context, int_cycle), options->gen.cycles, SZ_D); 2048 cmp_rdispr(code, options->gen.context_reg, offsetof(z80_context, int_cycle), options->gen.cycles, SZ_D);
2044 code_ptr skip_int = code->cur+1; 2049 code_ptr skip_int = code->cur+1;
2103 2108
2104 options->write_io = code->cur; 2109 options->write_io = code->cur;
2105 check_cycles(&options->gen); 2110 check_cycles(&options->gen);
2106 cycles(&options->gen, 4); 2111 cycles(&options->gen, 4);
2107 retn(code); 2112 retn(code);
2113
2114 options->read_16 = code->cur;
2115 cycles(&options->gen, 3);
2116 check_cycles(&options->gen);
2117 //TODO: figure out how to handle the extra wait state for word reads to bank area
2118 //may also need special handling to avoid too much stack depth when acces is blocked
2119 push_r(code, options->gen.scratch1);
2120 call(code, options->read_8_noinc);
2121 mov_rr(code, options->gen.scratch1, options->gen.scratch2, SZ_B);
2122 pop_r(code, options->gen.scratch1);
2123 add_ir(code, 1, options->gen.scratch1, SZ_W);
2124 cycles(&options->gen, 3);
2125 check_cycles(&options->gen);
2126 call(code, options->read_8_noinc);
2127 shl_ir(code, 8, options->gen.scratch1, SZ_W);
2128 mov_rr(code, options->gen.scratch2, options->gen.scratch1, SZ_B);
2129 retn(code);
2130
2131 options->write_16_highfirst = code->cur;
2132 cycles(&options->gen, 3);
2133 check_cycles(&options->gen);
2134 push_r(code, options->gen.scratch2);
2135 push_r(code, options->gen.scratch1);
2136 add_ir(code, 1, options->gen.scratch2, SZ_W);
2137 shr_ir(code, 8, options->gen.scratch1, SZ_W);
2138 call(code, options->write_8_noinc);
2139 pop_r(code, options->gen.scratch1);
2140 pop_r(code, options->gen.scratch2);
2141 cycles(&options->gen, 3);
2142 check_cycles(&options->gen);
2143 //TODO: Check if we can get away with TCO here
2144 call(code, options->write_8_noinc);
2145 retn(code);
2146
2147 options->write_16_lowfirst = code->cur;
2148 cycles(&options->gen, 3);
2149 check_cycles(&options->gen);
2150 push_r(code, options->gen.scratch2);
2151 push_r(code, options->gen.scratch1);
2152 call(code, options->write_8_noinc);
2153 pop_r(code, options->gen.scratch1);
2154 pop_r(code, options->gen.scratch2);
2155 add_ir(code, 1, options->gen.scratch2, SZ_W);
2156 shr_ir(code, 8, options->gen.scratch1, SZ_W);
2157 cycles(&options->gen, 3);
2158 check_cycles(&options->gen);
2159 //TODO: Check if we can get away with TCO here
2160 call(code, options->write_8_noinc);
2161 retn(code);
2108 2162
2109 options->retrans_stub = code->cur; 2163 options->retrans_stub = code->cur;
2110 //pop return address 2164 //pop return address
2111 pop_r(code, options->gen.scratch2); 2165 pop_r(code, options->gen.scratch2);
2112 call(code, options->gen.save_context); 2166 call(code, options->gen.save_context);
2128 push_r(code, R12); 2182 push_r(code, R12);
2129 push_r(code, R13); 2183 push_r(code, R13);
2130 push_r(code, R14); 2184 push_r(code, R14);
2131 push_r(code, R15); 2185 push_r(code, R15);
2132 mov_rr(code, RDI, options->gen.context_reg, SZ_PTR); 2186 mov_rr(code, RDI, options->gen.context_reg, SZ_PTR);
2187 call(code, options->load_context_scratch);
2133 cmp_irdisp(code, 0, options->gen.context_reg, offsetof(z80_context, extra_pc), SZ_PTR); 2188 cmp_irdisp(code, 0, options->gen.context_reg, offsetof(z80_context, extra_pc), SZ_PTR);
2134 code_ptr no_extra = code->cur+1; 2189 code_ptr no_extra = code->cur+1;
2135 jcc(code, CC_Z, no_extra); 2190 jcc(code, CC_Z, no_extra);
2136 push_rdisp(code, options->gen.context_reg, offsetof(z80_context, extra_pc)); 2191 push_rdisp(code, options->gen.context_reg, offsetof(z80_context, extra_pc));
2137 mov_irdisp(code, 0, options->gen.context_reg, offsetof(z80_context, extra_pc), SZ_PTR); 2192 mov_irdisp(code, 0, options->gen.context_reg, offsetof(z80_context, extra_pc), SZ_PTR);