comparison ztestgen.c @ 803:236a184bf6f0

Merge
author Michael Pavone <pavone@retrodev.com>
date Sun, 26 Jul 2015 16:51:03 -0700
parents 3072fb746601
children a6c6b621d0dc
comparison
equal deleted inserted replaced
802:6811f601008f 803:236a184bf6f0
22 extern char *z80_mnemonics[Z80_OTDR+1]; 22 extern char *z80_mnemonics[Z80_OTDR+1];
23 extern char * z80_regs[Z80_USE_IMMED]; 23 extern char * z80_regs[Z80_USE_IMMED];
24 #define PRE_IX 0xDD 24 #define PRE_IX 0xDD
25 #define PRE_IY 0xFD 25 #define PRE_IY 0xFD
26 #define LD_IR16 0x01 26 #define LD_IR16 0x01
27 #define INC_R8 0x04
27 #define LD_IR8 0x06 28 #define LD_IR8 0x06
28 #define LD_RR8 0x40 29 #define LD_RR8 0x40
29 #define AND_R 0xA0 30 #define AND_R 0xA0
30 #define PUSH 0xC5 31 #define PUSH 0xC5
31 #define POP 0xC1 32 #define POP 0xC1
139 reg = (reg - Z80_C) ^ 1; 140 reg = (reg - Z80_C) ^ 1;
140 } 141 }
141 *(dst++) = AND_R | reg; 142 *(dst++) = AND_R | reg;
142 return dst; 143 return dst;
143 } 144 }
145 }
146
147 uint8_t * inc_r(uint8_t *dst, uint8_t reg)
148 {
149 if (reg == Z80_IXH || reg == Z80_IXL) {
150 *(dst++) = PRE_IX;
151 return inc_r(dst, reg - (Z80_IXL - Z80_L));
152 } else if(reg == Z80_IYH || reg == Z80_IYL) {
153 *(dst++) = PRE_IY;
154 return inc_r(dst, reg - (Z80_IYL - Z80_L));
155 } else {
156 *(dst++) = INC_R8 | reg << 3;
157 return dst;
158 }
159 }
160
161 void mark_used8(uint8_t *reg_usage, uint16_t *reg_values, uint8_t reg, uint8_t init_value)
162 {
163 reg_usage[reg] = 1;
164 reg_values[reg] = init_value;
165 uint8_t word_reg = z80_word_reg(reg);
166 if (word_reg != Z80_UNUSED) {
167 reg_usage[word_reg] = 1;
168 reg_values[word_reg] = (reg_values[z80_high_reg(word_reg)] << 8) | (reg_values[z80_low_reg(word_reg)] & 0xFF);
169 }
170 }
171
172 uint8_t alloc_reg8(uint8_t *reg_usage, uint16_t *reg_values, uint8_t init_value)
173 {
174 for (uint8_t reg = 0; reg < Z80_BC; reg++)
175 {
176 if (!reg_usage[reg]) {
177 mark_used8(reg_usage, reg_values, reg, init_value);
178 return reg;
179 }
180 }
181 return Z80_UNUSED;
144 } 182 }
145 183
146 void z80_gen_test(z80inst * inst, uint8_t *instbuf, uint8_t instlen) 184 void z80_gen_test(z80inst * inst, uint8_t *instbuf, uint8_t instlen)
147 { 185 {
148 z80inst copy; 186 z80inst copy;
182 reg_values[z80_high_reg(inst->ea_reg)] = reg_values[inst->ea_reg] >> 8; 220 reg_values[z80_high_reg(inst->ea_reg)] = reg_values[inst->ea_reg] >> 8;
183 reg_usage[z80_high_reg(inst->ea_reg)] = 1; 221 reg_usage[z80_high_reg(inst->ea_reg)] = 1;
184 reg_values[z80_low_reg(inst->ea_reg)] = reg_values[inst->ea_reg] & 0xFF; 222 reg_values[z80_low_reg(inst->ea_reg)] = reg_values[inst->ea_reg] & 0xFF;
185 reg_usage[z80_low_reg(inst->ea_reg)] = 1; 223 reg_usage[z80_low_reg(inst->ea_reg)] = 1;
186 } else { 224 } else {
187 reg_values[inst->ea_reg] = rand() % 256; 225 mark_used8(reg_usage, reg_values, inst->ea_reg, rand() % 256);
188 uint8_t word_reg = z80_word_reg(inst->ea_reg);
189 if (word_reg != Z80_UNUSED) {
190 reg_usage[word_reg] = 1;
191 reg_values[word_reg] = (reg_values[z80_high_reg(word_reg)] << 8) | (reg_values[z80_low_reg(word_reg)] & 0xFF);
192 }
193 } 226 }
194 break; 227 break;
195 case Z80_REG_INDIRECT: 228 case Z80_REG_INDIRECT:
196 is_mem = 1; 229 is_mem = 1;
197 reg_values[inst->ea_reg] = 0x1000 + (rand() % 256 - 128); 230 reg_values[inst->ea_reg] = 0x1000 + (rand() % 256 - 128);
253 } 286 }
254 } 287 }
255 } 288 }
256 reg_usage[inst->reg] = 1; 289 reg_usage[inst->reg] = 1;
257 } 290 }
291 uint8_t counter_reg = Z80_UNUSED;
292 if (inst->op >= Z80_JP && inst->op <= Z80_JRCC) {
293 counter_reg = alloc_reg8(reg_usage, reg_values, 0);
294 }
258 puts("--------------"); 295 puts("--------------");
259 for (uint8_t reg = 0; reg < Z80_UNUSED; reg++) { 296 for (uint8_t reg = 0; reg < Z80_UNUSED; reg++) {
260 if (reg_values[reg]) { 297 if (reg_values[reg]) {
261 printf("%s: %X\n", z80_regs[reg], reg_values[reg]); 298 printf("%s: %X\n", z80_regs[reg], reg_values[reg]);
262 } 299 }
291 cur = push(cur, Z80_BC); 328 cur = push(cur, Z80_BC);
292 cur = pop(cur, Z80_AF); 329 cur = pop(cur, Z80_AF);
293 330
294 //setup other regs 331 //setup other regs
295 for (uint8_t reg = Z80_BC; reg <= Z80_IY; reg++) { 332 for (uint8_t reg = Z80_BC; reg <= Z80_IY; reg++) {
296 if (reg != Z80_AF && reg != Z80_SP) { 333 if (reg != Z80_AF && reg != Z80_SP && (inst->op != Z80_JP || addr_mode != Z80_REG_INDIRECT || inst->ea_reg != reg)) {
297 cur = ld_ir16(cur, reg, reg_values[reg]); 334 if (i == 1 && (z80_high_reg(reg) == counter_reg || z80_low_reg(reg) == counter_reg)) {
298 } 335 if (z80_high_reg(reg) == counter_reg) {
336 if (reg_usage[z80_low_reg(reg)]) {
337 cur = ld_ir8(cur, z80_low_reg(reg), reg_values[z80_low_reg(reg)]);
338 }
339 } else if (reg_usage[z80_high_reg(reg)]) {
340 cur = ld_ir8(cur, z80_high_reg(reg), reg_values[z80_high_reg(reg)]);
341 }
342 } else {
343 cur = ld_ir16(cur, reg, reg_values[reg]);
344 }
345 }
346 }
347
348 if (inst->op == Z80_JP && addr_mode == Z80_REG_INDIRECT) {
349 uint16_t address = cur - prog + (inst->ea_reg == Z80_HL ? 3 : 4) + instlen + 1 + i;
350 cur = ld_ir16(cur, inst->ea_reg, address);
299 } 351 }
300 352
301 //copy instruction 353 //copy instruction
302 if (instlen == 3) { 354 if (instlen == 3) {
303 memcpy(cur, instbuf, 2); 355 memcpy(cur, instbuf, 2);
308 } 360 }
309 361
310 //immed/displacement byte(s) 362 //immed/displacement byte(s)
311 if (addr_mode == Z80_IX_DISPLACE || addr_mode == Z80_IY_DISPLACE) { 363 if (addr_mode == Z80_IX_DISPLACE || addr_mode == Z80_IY_DISPLACE) {
312 *(cur++) = inst->ea_reg; 364 *(cur++) = inst->ea_reg;
365 } else if ((inst->op == Z80_JP || inst->op == Z80_JPCC) && addr_mode == Z80_IMMED) {
366 uint16_t address = cur - prog + 3 + i; //2 for immed address, 1/2 for instruction(s) to skip
367 *(cur++) = address;
368 *(cur++) = address >> 8;
369 } else if(inst->op == Z80_JR || inst->op == Z80_JRCC) {
370 *(cur++) = 1 + i; //skip one or 2 instructions based on value of i
313 } else if (addr_mode == Z80_IMMED & inst->op != Z80_IM) { 371 } else if (addr_mode == Z80_IMMED & inst->op != Z80_IM) {
314 *(cur++) = inst->immed & 0xFF; 372 *(cur++) = inst->immed & 0xFF;
315 if (word_sized) { 373 if (word_sized) {
316 *(cur++) = inst->immed >> 8; 374 *(cur++) = inst->immed >> 8;
317 } 375 }
322 if (inst->reg == Z80_USE_IMMED && inst->op != Z80_BIT && inst->op != Z80_RES && inst->op != Z80_SET) { 380 if (inst->reg == Z80_USE_IMMED && inst->op != Z80_BIT && inst->op != Z80_RES && inst->op != Z80_SET) {
323 *(cur++) = inst->immed & 0xFF; 381 *(cur++) = inst->immed & 0xFF;
324 } 382 }
325 if (instlen == 3) { 383 if (instlen == 3) {
326 *(cur++) = instbuf[2]; 384 *(cur++) = instbuf[2];
385 }
386 if (inst->op >= Z80_JP && inst->op <= Z80_JRCC) {
387 cur = inc_r(cur, counter_reg);
388 if (i) {
389 //inc twice on second iteration so we can differentiate the two
390 cur = inc_r(cur, counter_reg);
391 }
327 } 392 }
328 if (!i) { 393 if (!i) {
329 //Save AF from first run 394 //Save AF from first run
330 cur = push(cur, Z80_AF); 395 cur = push(cur, Z80_AF);
331 if (is_mem) { 396 if (is_mem) {
397 } 462 }
398 463
399 464
400 uint8_t should_skip(z80inst * inst) 465 uint8_t should_skip(z80inst * inst)
401 { 466 {
402 return inst->op >= Z80_JP || (inst->op >= Z80_LDI && inst->op <= Z80_CPDR) || inst->op == Z80_HALT 467 return inst->op >= Z80_DJNZ || (inst->op >= Z80_LDI && inst->op <= Z80_CPDR) || inst->op == Z80_HALT
403 || inst->op == Z80_DAA || inst->op == Z80_RLD || inst->op == Z80_RRD || inst->op == Z80_NOP 468 || inst->op == Z80_DAA || inst->op == Z80_RLD || inst->op == Z80_RRD || inst->op == Z80_NOP
404 || inst->op == Z80_DI || inst->op == Z80_EI; 469 || inst->op == Z80_DI || inst->op == Z80_EI;
405 } 470 }
406 471
407 void z80_gen_all() 472 void z80_gen_all()