Mercurial > repos > blastem
comparison ztestgen.c @ 400:a09aa6d067fd
Have test generator test both flag register 0 case and flag register FF case
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Sat, 15 Jun 2013 23:10:37 -0700 |
parents | 3f4f2b7318a1 |
children | 140af5509ce7 |
comparison
equal
deleted
inserted
replaced
399:acaae7c3d34c | 400:a09aa6d067fd |
---|---|
19 #define PRE_IX 0xDD | 19 #define PRE_IX 0xDD |
20 #define PRE_IY 0xFD | 20 #define PRE_IY 0xFD |
21 #define LD_IR16 0x01 | 21 #define LD_IR16 0x01 |
22 #define LD_IR8 0x06 | 22 #define LD_IR8 0x06 |
23 #define LD_RR8 0x40 | 23 #define LD_RR8 0x40 |
24 #define AND_R 0xA0 | |
24 #define PUSH 0xC5 | 25 #define PUSH 0xC5 |
25 #define POP 0xC1 | 26 #define POP 0xC1 |
26 | 27 |
27 uint8_t * ld_ir16(uint8_t * dst, uint8_t reg, uint16_t val) | 28 uint8_t * ld_ir16(uint8_t * dst, uint8_t reg, uint16_t val) |
28 { | 29 { |
112 } else { | 113 } else { |
113 if (reg == Z80_AF) { | 114 if (reg == Z80_AF) { |
114 reg--; | 115 reg--; |
115 } | 116 } |
116 *(dst++) = POP | ((reg - Z80_BC) << 4); | 117 *(dst++) = POP | ((reg - Z80_BC) << 4); |
118 return dst; | |
119 } | |
120 } | |
121 | |
122 uint8_t * and_r(uint8_t * dst, uint8_t reg) | |
123 { | |
124 if (reg == Z80_IXH || reg == Z80_IXL) { | |
125 *(dst++) = PRE_IX; | |
126 return and_r(dst, reg - (Z80_IXL - Z80_L)); | |
127 } else if(reg == Z80_IYH || reg == Z80_IYL) { | |
128 *(dst++) = PRE_IY; | |
129 return and_r(dst, reg - (Z80_IYL - Z80_L)); | |
130 } else { | |
131 if (reg == Z80_A) { | |
132 reg = 7; | |
133 } else { | |
134 reg = (reg - Z80_C) ^ 1; | |
135 } | |
136 *(dst++) = AND_R | reg; | |
117 return dst; | 137 return dst; |
118 } | 138 } |
119 } | 139 } |
120 | 140 |
121 void z80_gen_test(z80inst * inst, uint8_t *instbuf, uint8_t instlen) | 141 void z80_gen_test(z80inst * inst, uint8_t *instbuf, uint8_t instlen) |
249 uint8_t mem_val; | 269 uint8_t mem_val; |
250 //disable interrupts | 270 //disable interrupts |
251 *(cur++) = 0xF3; | 271 *(cur++) = 0xF3; |
252 //setup SP | 272 //setup SP |
253 cur = ld_ir16(cur, Z80_SP, 0x2000); | 273 cur = ld_ir16(cur, Z80_SP, 0x2000); |
254 //setup memory | 274 for (int i = 0; i < 2; i ++) { |
255 if (is_mem) { | 275 //setup memory |
256 mem_val = rand() % 256; | 276 if (is_mem) { |
257 cur = ld_ir8(cur, Z80_A, mem_val); | 277 mem_val = rand() % 256; |
258 cur = ld_amem(cur, address); | 278 cur = ld_ir8(cur, Z80_A, mem_val); |
259 } | 279 cur = ld_amem(cur, address); |
260 //setup AF | 280 } |
261 cur = ld_ir16(cur, Z80_BC, reg_values[Z80_A] << 8); | 281 //setup AF |
262 cur = push(cur, Z80_BC); | 282 cur = ld_ir16(cur, Z80_BC, reg_values[Z80_A] << 8 | (i ? 0xFF : 0)); |
263 cur = pop(cur, Z80_AF); | 283 cur = push(cur, Z80_BC); |
284 cur = pop(cur, Z80_AF); | |
264 | 285 |
265 //setup other regs | 286 //setup other regs |
266 for (uint8_t reg = Z80_BC; reg <= Z80_IY; reg++) { | 287 for (uint8_t reg = Z80_BC; reg <= Z80_IY; reg++) { |
267 if (reg != Z80_AF && reg != Z80_SP) { | 288 if (reg != Z80_AF && reg != Z80_SP) { |
268 cur = ld_ir16(cur, reg, reg_values[reg]); | 289 cur = ld_ir16(cur, reg, reg_values[reg]); |
269 } | 290 } |
270 } | 291 } |
271 | 292 |
272 //copy instruction | 293 //copy instruction |
273 if (instlen == 3) { | 294 if (instlen == 3) { |
274 memcpy(cur, instbuf, 2); | 295 memcpy(cur, instbuf, 2); |
275 cur += 2; | 296 cur += 2; |
276 } else { | 297 } else { |
277 memcpy(cur, instbuf, instlen); | 298 memcpy(cur, instbuf, instlen); |
278 cur += instlen; | 299 cur += instlen; |
279 } | 300 } |
280 | 301 |
281 //immed/displacement byte(s) | 302 //immed/displacement byte(s) |
282 if (addr_mode == Z80_IX_DISPLACE || addr_mode == Z80_IY_DISPLACE) { | 303 if (addr_mode == Z80_IX_DISPLACE || addr_mode == Z80_IY_DISPLACE) { |
283 *(cur++) = inst->ea_reg; | 304 *(cur++) = inst->ea_reg; |
284 } else if (addr_mode == Z80_IMMED & inst->op != Z80_IM) { | 305 } else if (addr_mode == Z80_IMMED & inst->op != Z80_IM) { |
285 *(cur++) = inst->immed & 0xFF; | 306 *(cur++) = inst->immed & 0xFF; |
286 if (word_sized) { | 307 if (word_sized) { |
308 *(cur++) = inst->immed >> 8; | |
309 } | |
310 } else if (addr_mode == Z80_IMMED_INDIRECT) { | |
311 *(cur++) = inst->immed & 0xFF; | |
287 *(cur++) = inst->immed >> 8; | 312 *(cur++) = inst->immed >> 8; |
288 } | 313 } |
289 } else if (addr_mode == Z80_IMMED_INDIRECT) { | 314 if (inst->reg == Z80_USE_IMMED && inst->op != Z80_BIT && inst->op != Z80_RES && inst->op != Z80_SET) { |
290 *(cur++) = inst->immed & 0xFF; | 315 *(cur++) = inst->immed & 0xFF; |
291 *(cur++) = inst->immed >> 8; | 316 } |
292 } | 317 if (instlen == 3) { |
293 if (inst->reg == Z80_USE_IMMED && inst->op != Z80_BIT && inst->op != Z80_RES && inst->op != Z80_SET) { | 318 *(cur++) = instbuf[2]; |
294 *(cur++) = inst->immed & 0xFF; | 319 } |
295 } | 320 if (!i) { |
296 if (instlen == 3) { | 321 //Save AF from first run |
297 *(cur++) = instbuf[2]; | 322 cur = push(cur, Z80_AF); |
323 } else { | |
324 //Pop AF from first run for final result | |
325 for (int reg = Z80_BC; reg <= Z80_IY; reg++) { | |
326 if (reg != Z80_AF && !reg_usage[reg]) { | |
327 cur = pop(cur, reg); | |
328 cur = push(cur, Z80_AF); | |
329 cur = ld_ir8(cur, Z80_A, 0xC7); | |
330 cur = and_r(cur, z80_low_reg(reg)); | |
331 cur = ld_rr8(cur, Z80_A, z80_low_reg(reg)); | |
332 cur = pop(cur, Z80_AF); | |
333 reg_usage[reg] = 1; | |
334 reg_usage[z80_low_reg(reg)] = 1; | |
335 break; | |
336 } | |
337 } | |
338 } | |
298 } | 339 } |
299 | 340 |
300 for (char * cur = disbuf; *cur != 0; cur++) { | 341 for (char * cur = disbuf; *cur != 0; cur++) { |
301 if (*cur == ',' || *cur == ' ') { | 342 if (*cur == ',' || *cur == ' ') { |
302 *cur = '_'; | 343 *cur = '_'; |