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