Mercurial > repos > blastem
comparison ztestgen.c @ 391:3f4f2b7318a1
Check memory results in ztestgen
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Sat, 08 Jun 2013 12:59:23 -0700 |
parents | 170722e80fc0 |
children | a09aa6d067fd |
comparison
equal
deleted
inserted
replaced
390:561fe3ea3fc8 | 391:3f4f2b7318a1 |
---|---|
18 extern char * z80_regs[Z80_USE_IMMED]; | 18 extern char * z80_regs[Z80_USE_IMMED]; |
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 PUSH 0xC5 | 24 #define PUSH 0xC5 |
24 #define POP 0xC1 | 25 #define POP 0xC1 |
25 | 26 |
26 uint8_t * ld_ir16(uint8_t * dst, uint8_t reg, uint16_t val) | 27 uint8_t * ld_ir16(uint8_t * dst, uint8_t reg, uint16_t val) |
27 { | 28 { |
49 *(dst++) = LD_IR8 | (reg << 3); | 50 *(dst++) = LD_IR8 | (reg << 3); |
50 *(dst++) = val; | 51 *(dst++) = val; |
51 return dst; | 52 return dst; |
52 } | 53 } |
53 | 54 |
55 uint8_t * ld_rr8(uint8_t * dst, uint8_t src, uint8_t dstr) | |
56 { | |
57 if (src <= Z80_H) { | |
58 src = (src - Z80_C) ^ 1; | |
59 } else { | |
60 src = 0x7; | |
61 } | |
62 if (dstr <= Z80_H) { | |
63 dstr = (dstr - Z80_C) ^ 1; | |
64 } else { | |
65 dstr = 0x7; | |
66 } | |
67 *(dst++) = LD_RR8 | (dstr << 3) | src; | |
68 return dst; | |
69 } | |
70 | |
54 uint8_t * ld_amem(uint8_t * dst, uint16_t address) | 71 uint8_t * ld_amem(uint8_t * dst, uint16_t address) |
55 { | 72 { |
56 *(dst++) = 0x32; | 73 *(dst++) = 0x32; |
74 *(dst++) = address & 0xFF; | |
75 *(dst++) = address >> 8; | |
76 return dst; | |
77 } | |
78 | |
79 uint8_t * ld_mema(uint8_t * dst, uint16_t address) | |
80 { | |
81 *(dst++) = 0x3A; | |
57 *(dst++) = address & 0xFF; | 82 *(dst++) = address & 0xFF; |
58 *(dst++) = address >> 8; | 83 *(dst++) = address >> 8; |
59 return dst; | 84 return dst; |
60 } | 85 } |
61 | 86 |
95 | 120 |
96 void z80_gen_test(z80inst * inst, uint8_t *instbuf, uint8_t instlen) | 121 void z80_gen_test(z80inst * inst, uint8_t *instbuf, uint8_t instlen) |
97 { | 122 { |
98 z80inst copy; | 123 z80inst copy; |
99 uint16_t reg_values[Z80_UNUSED]; | 124 uint16_t reg_values[Z80_UNUSED]; |
125 uint8_t reg_usage[Z80_UNUSED]; | |
100 memset(reg_values, 0, sizeof(reg_values)); | 126 memset(reg_values, 0, sizeof(reg_values)); |
127 memset(reg_usage, 0, sizeof(reg_usage)); | |
101 uint8_t addr_mode = inst->addr_mode & 0x1F; | 128 uint8_t addr_mode = inst->addr_mode & 0x1F; |
102 uint8_t word_sized = ((inst->reg != Z80_USE_IMMED && inst->reg != Z80_UNUSED && inst->reg >= Z80_BC) || (addr_mode == Z80_REG && inst->ea_reg >= Z80_BC)) ? 1 : 0; | 129 uint8_t word_sized = ((inst->reg != Z80_USE_IMMED && inst->reg != Z80_UNUSED && inst->reg >= Z80_BC) || (addr_mode == Z80_REG && inst->ea_reg >= Z80_BC)) ? 1 : 0; |
103 | 130 |
104 if (inst->reg == Z80_USE_IMMED || addr_mode == Z80_IMMED || addr_mode == Z80_IMMED_INDIRECT | 131 if (inst->reg == Z80_USE_IMMED || addr_mode == Z80_IMMED || addr_mode == Z80_IMMED_INDIRECT |
105 || addr_mode == Z80_IX_DISPLACE || addr_mode == Z80_IY_DISPLACE) | 132 || addr_mode == Z80_IX_DISPLACE || addr_mode == Z80_IY_DISPLACE) |
122 uint16_t address; | 149 uint16_t address; |
123 int16_t offset; | 150 int16_t offset; |
124 switch(addr_mode) | 151 switch(addr_mode) |
125 { | 152 { |
126 case Z80_REG: | 153 case Z80_REG: |
154 reg_usage[inst->ea_reg] = 1; | |
127 if (word_sized) { | 155 if (word_sized) { |
128 reg_values[inst->ea_reg] = rand() % 65536; | 156 reg_values[inst->ea_reg] = rand() % 65536; |
129 reg_values[z80_high_reg(inst->ea_reg)] = reg_values[inst->ea_reg] >> 8; | 157 reg_values[z80_high_reg(inst->ea_reg)] = reg_values[inst->ea_reg] >> 8; |
158 reg_usage[z80_high_reg(inst->ea_reg)] = 1; | |
130 reg_values[z80_low_reg(inst->ea_reg)] = reg_values[inst->ea_reg] & 0xFF; | 159 reg_values[z80_low_reg(inst->ea_reg)] = reg_values[inst->ea_reg] & 0xFF; |
160 reg_usage[z80_low_reg(inst->ea_reg)] = 1; | |
131 } else { | 161 } else { |
132 reg_values[inst->ea_reg] = rand() % 256; | 162 reg_values[inst->ea_reg] = rand() % 256; |
133 uint8_t word_reg = z80_word_reg(inst->ea_reg); | 163 uint8_t word_reg = z80_word_reg(inst->ea_reg); |
134 if (word_reg != Z80_UNUSED) { | 164 if (word_reg != Z80_UNUSED) { |
165 reg_usage[word_reg] = 1; | |
135 reg_values[word_reg] = (reg_values[z80_high_reg(word_reg)] << 8) | (reg_values[z80_low_reg(word_reg)] & 0xFF); | 166 reg_values[word_reg] = (reg_values[z80_high_reg(word_reg)] << 8) | (reg_values[z80_low_reg(word_reg)] & 0xFF); |
136 } | 167 } |
137 } | 168 } |
138 break; | 169 break; |
139 case Z80_REG_INDIRECT: | 170 case Z80_REG_INDIRECT: |
140 is_mem = 1; | 171 is_mem = 1; |
141 reg_values[inst->ea_reg] = 0x1000 + (rand() % 256 - 128); | 172 reg_values[inst->ea_reg] = 0x1000 + (rand() % 256 - 128); |
173 reg_usage[inst->ea_reg] = 1; | |
142 address = reg_values[inst->ea_reg]; | 174 address = reg_values[inst->ea_reg]; |
175 reg_usage[z80_high_reg(inst->ea_reg)] = 1; | |
143 reg_values[z80_high_reg(inst->ea_reg)] = reg_values[inst->ea_reg] >> 8; | 176 reg_values[z80_high_reg(inst->ea_reg)] = reg_values[inst->ea_reg] >> 8; |
177 reg_usage[z80_low_reg(inst->ea_reg)] = 1; | |
144 reg_values[z80_low_reg(inst->ea_reg)] = reg_values[inst->ea_reg] & 0xFF; | 178 reg_values[z80_low_reg(inst->ea_reg)] = reg_values[inst->ea_reg] & 0xFF; |
145 break; | 179 break; |
146 case Z80_IMMED_INDIRECT: | 180 case Z80_IMMED_INDIRECT: |
147 is_mem = 1; | 181 is_mem = 1; |
148 address = inst->immed; | 182 address = inst->immed; |
149 break; | 183 break; |
150 case Z80_IX_DISPLACE: | 184 case Z80_IX_DISPLACE: |
151 reg_values[Z80_IX] = 0x1000; | 185 reg_values[Z80_IX] = 0x1000; |
186 reg_usage[Z80_IX] = 1; | |
152 reg_values[Z80_IXH] = 0x10; | 187 reg_values[Z80_IXH] = 0x10; |
188 reg_usage[Z80_IXH] = 1; | |
153 reg_values[Z80_IXL] = 0; | 189 reg_values[Z80_IXL] = 0; |
190 reg_usage[Z80_IXL] = 1; | |
154 is_mem = 1; | 191 is_mem = 1; |
155 offset = inst->ea_reg; | 192 offset = inst->ea_reg; |
156 if (offset > 0x7F) { | 193 if (offset > 0x7F) { |
157 offset -= 256; | 194 offset -= 256; |
158 } | 195 } |
159 address = 0x1000 + offset; | 196 address = 0x1000 + offset; |
160 break; | 197 break; |
161 case Z80_IY_DISPLACE: | 198 case Z80_IY_DISPLACE: |
162 reg_values[Z80_IY] = 0x1000; | 199 reg_values[Z80_IY] = 0x1000; |
200 reg_usage[Z80_IY] = 1; | |
163 reg_values[Z80_IYH] = 0x10; | 201 reg_values[Z80_IYH] = 0x10; |
202 reg_usage[Z80_IYH] = 1; | |
164 reg_values[Z80_IYL] = 0; | 203 reg_values[Z80_IYL] = 0; |
204 reg_usage[Z80_IYL] = 1; | |
165 is_mem = 1; | 205 is_mem = 1; |
166 offset = inst->ea_reg; | 206 offset = inst->ea_reg; |
167 if (offset > 0x7F) { | 207 if (offset > 0x7F) { |
168 offset -= 256; | 208 offset -= 256; |
169 } | 209 } |
170 address = 0x1000 + offset; | 210 address = 0x1000 + offset; |
171 break; | 211 break; |
172 } | 212 } |
173 if (inst->reg != Z80_UNUSED && inst->reg != Z80_USE_IMMED) { | 213 if (inst->reg != Z80_UNUSED && inst->reg != Z80_USE_IMMED) { |
214 reg_usage[inst->reg] = 1; | |
174 if (word_sized) { | 215 if (word_sized) { |
175 reg_values[inst->reg] = rand() % 65536; | 216 reg_values[inst->reg] = rand() % 65536; |
217 reg_usage[z80_high_reg(inst->reg)] = 1; | |
176 reg_values[z80_high_reg(inst->reg)] = reg_values[inst->reg] >> 8; | 218 reg_values[z80_high_reg(inst->reg)] = reg_values[inst->reg] >> 8; |
219 reg_usage[z80_low_reg(inst->reg)] = 1; | |
177 reg_values[z80_low_reg(inst->reg)] = reg_values[inst->reg] & 0xFF; | 220 reg_values[z80_low_reg(inst->reg)] = reg_values[inst->reg] & 0xFF; |
178 } else { | 221 } else { |
179 reg_values[inst->reg] = rand() % 255; | 222 reg_values[inst->reg] = rand() % 255; |
180 uint8_t word_reg = z80_word_reg(inst->reg); | 223 uint8_t word_reg = z80_word_reg(inst->reg); |
181 if (word_reg != Z80_UNUSED) { | 224 if (word_reg != Z80_UNUSED) { |
225 reg_usage[word_reg] = 1; | |
182 reg_values[word_reg] = (reg_values[z80_high_reg(word_reg)] << 8) | (reg_values[z80_low_reg(word_reg)] & 0xFF); | 226 reg_values[word_reg] = (reg_values[z80_high_reg(word_reg)] << 8) | (reg_values[z80_low_reg(word_reg)] & 0xFF); |
183 } | 227 } |
184 } | 228 } |
185 } | 229 } |
186 puts("--------------"); | 230 puts("--------------"); |
188 if (reg_values[reg]) { | 232 if (reg_values[reg]) { |
189 printf("%s: %X\n", z80_regs[reg], reg_values[reg]); | 233 printf("%s: %X\n", z80_regs[reg], reg_values[reg]); |
190 } | 234 } |
191 } | 235 } |
192 char disbuf[80]; | 236 char disbuf[80]; |
193 z80_disasm(inst, disbuf); | 237 z80_disasm(inst, disbuf, 0); |
194 puts(disbuf); | 238 puts(disbuf); |
195 char pathbuf[128]; | 239 char pathbuf[128]; |
196 sprintf(pathbuf, "ztests/%s", z80_mnemonics[inst->op]); | 240 sprintf(pathbuf, "ztests/%s", z80_mnemonics[inst->op]); |
197 if (mkdir(pathbuf, 0777) != 0) { | 241 if (mkdir(pathbuf, 0777) != 0) { |
198 if (errno != EEXIST) { | 242 if (errno != EEXIST) { |
256 for (char * cur = disbuf; *cur != 0; cur++) { | 300 for (char * cur = disbuf; *cur != 0; cur++) { |
257 if (*cur == ',' || *cur == ' ') { | 301 if (*cur == ',' || *cur == ' ') { |
258 *cur = '_'; | 302 *cur = '_'; |
259 } | 303 } |
260 } | 304 } |
305 //save memory result | |
306 if (is_mem) { | |
307 if (reg_usage[Z80_A]) { | |
308 cur = push(cur, Z80_AF); | |
309 } | |
310 cur = ld_mema(cur, address); | |
311 if (reg_usage[Z80_A]) { | |
312 for (int reg = 0; reg < Z80_I; reg++) { | |
313 if (!reg_usage[reg]) { | |
314 cur = ld_rr8(cur, Z80_A, reg); | |
315 break; | |
316 } | |
317 } | |
318 cur = pop(cur, Z80_AF); | |
319 } | |
320 } | |
321 | |
261 //halt | 322 //halt |
262 *(cur++) = 0x76; | 323 *(cur++) = 0x76; |
263 sprintf(pathbuf + strlen(pathbuf), "/%s.bin", disbuf); | 324 sprintf(pathbuf + strlen(pathbuf), "/%s.bin", disbuf); |
264 FILE * progfile = fopen(pathbuf, "wb"); | 325 FILE * progfile = fopen(pathbuf, "wb"); |
265 fwrite(prog, 1, cur - prog, progfile); | 326 fwrite(prog, 1, cur - prog, progfile); |