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);