Mercurial > repos > blastem
comparison z80_to_x86.c @ 312:cf7ecda060c7
Properly handle instructions that use boty IYH and IYL
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Thu, 09 May 2013 18:36:21 -0700 |
parents | 56fcbfb8767a |
children | a13329645ea3 |
comparison
equal
deleted
inserted
replaced
311:56fcbfb8767a | 312:cf7ecda060c7 |
---|---|
71 } else if ((inst->reg & 0x1F) == Z80_UNUSED) { | 71 } else if ((inst->reg & 0x1F) == Z80_UNUSED) { |
72 ea->mode = MODE_UNUSED; | 72 ea->mode = MODE_UNUSED; |
73 } else { | 73 } else { |
74 ea->mode = MODE_REG_DIRECT; | 74 ea->mode = MODE_REG_DIRECT; |
75 if (inst->reg == Z80_IYH) { | 75 if (inst->reg == Z80_IYH) { |
76 ea->base = opts->regs[Z80_IYL]; | 76 if ((inst->addr_mode & 0x1F) == Z80_REG && inst->ea_reg == Z80_IYL) { |
77 dst = ror_ir(dst, 8, opts->regs[Z80_IY], SZ_W); | 77 dst = mov_rr(dst, opts->regs[Z80_IY], SCRATCH1, SZ_W); |
78 dst = ror_ir(dst, 8, SCRATCH1, SZ_W); | |
79 ea->base = SCRATCH1; | |
80 } else { | |
81 ea->base = opts->regs[Z80_IYL]; | |
82 dst = ror_ir(dst, 8, opts->regs[Z80_IY], SZ_W); | |
83 } | |
78 } else if(opts->regs[inst->reg] >= 0) { | 84 } else if(opts->regs[inst->reg] >= 0) { |
79 ea->base = opts->regs[inst->reg]; | 85 ea->base = opts->regs[inst->reg]; |
80 if (ea->base >= AH && ea->base <= BH) { | 86 if (ea->base >= AH && ea->base <= BH) { |
81 if ((inst->addr_mode & 0x1F) == Z80_REG) { | 87 if ((inst->addr_mode & 0x1F) == Z80_REG) { |
82 uint8_t other_reg = opts->regs[inst->ea_reg]; | 88 uint8_t other_reg = opts->regs[inst->ea_reg]; |
101 } | 107 } |
102 | 108 |
103 uint8_t * z80_save_reg(uint8_t * dst, z80inst * inst, x86_z80_options * opts) | 109 uint8_t * z80_save_reg(uint8_t * dst, z80inst * inst, x86_z80_options * opts) |
104 { | 110 { |
105 if (inst->reg == Z80_IYH) { | 111 if (inst->reg == Z80_IYH) { |
106 dst = ror_ir(dst, 8, opts->regs[Z80_IY], SZ_W); | 112 if ((inst->addr_mode & 0x1F) == Z80_REG && inst->ea_reg == Z80_IYL) { |
113 dst = ror_ir(dst, 8, opts->regs[Z80_IY], SZ_W); | |
114 dst = mov_rr(dst, SCRATCH1, opts->regs[Z80_IYL], SZ_B); | |
115 dst = ror_ir(dst, 8, opts->regs[Z80_IY], SZ_W); | |
116 } else { | |
117 dst = ror_ir(dst, 8, opts->regs[Z80_IY], SZ_W); | |
118 } | |
107 } else if (opts->regs[inst->reg] >= AH && opts->regs[inst->reg] <= BH) { | 119 } else if (opts->regs[inst->reg] >= AH && opts->regs[inst->reg] <= BH) { |
108 if ((inst->addr_mode & 0x1F) == Z80_REG) { | 120 if ((inst->addr_mode & 0x1F) == Z80_REG) { |
109 uint8_t other_reg = opts->regs[inst->ea_reg]; | 121 uint8_t other_reg = opts->regs[inst->ea_reg]; |
110 if (other_reg >= R8 || (other_reg >= RSP && other_reg <= RDI)) { | 122 if (other_reg >= R8 || (other_reg >= RSP && other_reg <= RDI)) { |
111 //we can't mix an *H reg with a register that requires the REX prefix | 123 //we can't mix an *H reg with a register that requires the REX prefix |
126 areg = read ? SCRATCH1 : SCRATCH2; | 138 areg = read ? SCRATCH1 : SCRATCH2; |
127 switch(inst->addr_mode & 0x1F) | 139 switch(inst->addr_mode & 0x1F) |
128 { | 140 { |
129 case Z80_REG: | 141 case Z80_REG: |
130 if (inst->ea_reg == Z80_IYH) { | 142 if (inst->ea_reg == Z80_IYH) { |
131 ea->base = opts->regs[Z80_IYL]; | 143 if (inst->reg == Z80_IYL) { |
132 dst = ror_ir(dst, 8, opts->regs[Z80_IY], SZ_W); | 144 dst = mov_rr(dst, opts->regs[Z80_IY], SCRATCH1, SZ_W); |
145 dst = ror_ir(dst, 8, SCRATCH1, SZ_W); | |
146 ea->base = SCRATCH1; | |
147 } else { | |
148 ea->base = opts->regs[Z80_IYL]; | |
149 dst = ror_ir(dst, 8, opts->regs[Z80_IY], SZ_W); | |
150 } | |
133 } else { | 151 } else { |
134 ea->base = opts->regs[inst->ea_reg]; | 152 ea->base = opts->regs[inst->ea_reg]; |
135 if (ea->base >= AH && ea->base <= BH && inst->reg != Z80_UNUSED && inst->reg != Z80_USE_IMMED) { | 153 if (ea->base >= AH && ea->base <= BH && inst->reg != Z80_UNUSED && inst->reg != Z80_USE_IMMED) { |
136 uint8_t other_reg = opts->regs[inst->reg]; | 154 uint8_t other_reg = opts->regs[inst->reg]; |
137 if (other_reg >= R8 || (other_reg >= RSP && other_reg <= RDI)) { | 155 if (other_reg >= R8 || (other_reg >= RSP && other_reg <= RDI)) { |
220 | 238 |
221 uint8_t * z80_save_ea(uint8_t * dst, z80inst * inst, x86_z80_options * opts) | 239 uint8_t * z80_save_ea(uint8_t * dst, z80inst * inst, x86_z80_options * opts) |
222 { | 240 { |
223 if ((inst->addr_mode & 0x1F) == Z80_REG) { | 241 if ((inst->addr_mode & 0x1F) == Z80_REG) { |
224 if (inst->ea_reg == Z80_IYH) { | 242 if (inst->ea_reg == Z80_IYH) { |
225 dst = ror_ir(dst, 8, opts->regs[Z80_IY], SZ_W); | 243 if (inst->reg == Z80_IYL) { |
244 dst = ror_ir(dst, 8, opts->regs[Z80_IY], SZ_W); | |
245 dst = mov_rr(dst, SCRATCH1, opts->regs[Z80_IYL], SZ_B); | |
246 dst = ror_ir(dst, 8, opts->regs[Z80_IY], SZ_W); | |
247 } else { | |
248 dst = ror_ir(dst, 8, opts->regs[Z80_IY], SZ_W); | |
249 } | |
226 } else if (inst->reg != Z80_UNUSED && inst->reg != Z80_USE_IMMED && opts->regs[inst->ea_reg] >= AH && opts->regs[inst->ea_reg] <= BH) { | 250 } else if (inst->reg != Z80_UNUSED && inst->reg != Z80_USE_IMMED && opts->regs[inst->ea_reg] >= AH && opts->regs[inst->ea_reg] <= BH) { |
227 uint8_t other_reg = opts->regs[inst->reg]; | 251 uint8_t other_reg = opts->regs[inst->reg]; |
228 if (other_reg >= R8 || (other_reg >= RSP && other_reg <= RDI)) { | 252 if (other_reg >= R8 || (other_reg >= RSP && other_reg <= RDI)) { |
229 //we can't mix an *H reg with a register that requires the REX prefix | 253 //we can't mix an *H reg with a register that requires the REX prefix |
230 dst = ror_ir(dst, 8, opts->regs[z80_low_reg(inst->ea_reg)], SZ_W); | 254 dst = ror_ir(dst, 8, opts->regs[z80_low_reg(inst->ea_reg)], SZ_W); |