Mercurial > repos > blastem
comparison backend_x86.c @ 2054:8ee7ecbf3f21 segacd
Implement enough of Sega CD gate array and Sub CPU to pass Sik's Mode 1 test ROM
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Tue, 18 Jan 2022 00:03:50 -0800 |
parents | 45c4b74e7676 |
children | afc54649ebed |
comparison
equal
deleted
inserted
replaced
2053:3414a4423de1 | 2054:8ee7ecbf3f21 |
---|---|
114 } | 114 } |
115 cycles(opts, opts->bus_cycles); | 115 cycles(opts, opts->bus_cycles); |
116 if (after_inc) { | 116 if (after_inc) { |
117 *after_inc = code->cur; | 117 *after_inc = code->cur; |
118 } | 118 } |
119 | 119 |
120 if (opts->address_size == SZ_D && opts->address_mask != 0xFFFFFFFF) { | 120 if (opts->address_size == SZ_D && opts->address_mask != 0xFFFFFFFF) { |
121 and_ir(code, opts->address_mask, adr_reg, SZ_D); | 121 and_ir(code, opts->address_mask, adr_reg, SZ_D); |
122 } else if (opts->address_size == SZ_W && opts->address_mask != 0xFFFF) { | 122 } else if (opts->address_size == SZ_W && opts->address_mask != 0xFFFF) { |
123 and_ir(code, opts->address_mask, adr_reg, SZ_W); | 123 and_ir(code, opts->address_mask, adr_reg, SZ_W); |
124 } | 124 } |
125 code_ptr lb_jcc = NULL, ub_jcc = NULL; | 125 code_ptr lb_jcc = NULL, ub_jcc = NULL; |
126 uint16_t access_flag = is_write ? MMAP_WRITE : MMAP_READ; | 126 uint16_t access_flag = is_write ? MMAP_WRITE : MMAP_READ; |
127 uint32_t ram_flags_off = opts->ram_flags_off; | 127 uint32_t ram_flags_off = opts->ram_flags_off; |
128 uint32_t min_address = 0; | 128 uint32_t min_address = 0; |
129 uint32_t max_address = opts->max_address; | 129 uint32_t max_address = opts->max_address; |
130 uint8_t need_wide_jcc = 0; | |
130 for (uint32_t chunk = 0; chunk < num_chunks; chunk++) | 131 for (uint32_t chunk = 0; chunk < num_chunks; chunk++) |
131 { | 132 { |
133 code_info chunk_start = *code; | |
132 if (memmap[chunk].start > min_address) { | 134 if (memmap[chunk].start > min_address) { |
133 cmp_ir(code, memmap[chunk].start, adr_reg, opts->address_size); | 135 cmp_ir(code, memmap[chunk].start, adr_reg, opts->address_size); |
134 lb_jcc = code->cur + 1; | 136 lb_jcc = code->cur + 1; |
135 jcc(code, CC_C, code->cur + 2); | 137 if (need_wide_jcc) { |
138 jcc(code, CC_C, code->cur + 130); | |
139 lb_jcc++; | |
140 } else { | |
141 jcc(code, CC_C, code->cur + 2); | |
142 } | |
136 } else { | 143 } else { |
137 min_address = memmap[chunk].end; | 144 min_address = memmap[chunk].end; |
138 } | 145 } |
139 if (memmap[chunk].end < max_address) { | 146 if (memmap[chunk].end < max_address) { |
140 cmp_ir(code, memmap[chunk].end, adr_reg, opts->address_size); | 147 cmp_ir(code, memmap[chunk].end, adr_reg, opts->address_size); |
141 ub_jcc = code->cur + 1; | 148 ub_jcc = code->cur + 1; |
142 jcc(code, CC_NC, code->cur + 2); | 149 if (need_wide_jcc) { |
150 jcc(code, CC_NC, code->cur + 130); | |
151 ub_jcc++; | |
152 } else { | |
153 jcc(code, CC_NC, code->cur + 2); | |
154 } | |
143 } else { | 155 } else { |
144 max_address = memmap[chunk].start; | 156 max_address = memmap[chunk].start; |
145 } | 157 } |
146 | 158 |
147 if (memmap[chunk].mask != opts->address_mask) { | 159 if (memmap[chunk].mask != opts->address_mask) { |
310 } else { | 322 } else { |
311 ram_flags_off += 1; | 323 ram_flags_off += 1; |
312 } | 324 } |
313 } | 325 } |
314 if (lb_jcc) { | 326 if (lb_jcc) { |
315 *lb_jcc = code->cur - (lb_jcc+1); | 327 if (need_wide_jcc) { |
328 *((int32_t*)lb_jcc) = code->cur - (lb_jcc+4); | |
329 } else if (code->cur - (lb_jcc+1) > 0x7f) { | |
330 need_wide_jcc = 1; | |
331 chunk--; | |
332 *code = chunk_start; | |
333 continue; | |
334 } else { | |
335 *lb_jcc = code->cur - (lb_jcc+1); | |
336 } | |
316 lb_jcc = NULL; | 337 lb_jcc = NULL; |
317 } | 338 } |
318 if (ub_jcc) { | 339 if (ub_jcc) { |
319 *ub_jcc = code->cur - (ub_jcc+1); | 340 if (need_wide_jcc) { |
341 *((int32_t*)ub_jcc) = code->cur - (ub_jcc+4); | |
342 } else if (code->cur - (ub_jcc+1) > 0x7f) { | |
343 need_wide_jcc = 1; | |
344 chunk--; | |
345 *code = chunk_start; | |
346 continue; | |
347 } else { | |
348 *ub_jcc = code->cur - (ub_jcc+1); | |
349 } | |
350 | |
320 ub_jcc = NULL; | 351 ub_jcc = NULL; |
352 } | |
353 if (need_wide_jcc) { | |
354 need_wide_jcc = 0; | |
321 } | 355 } |
322 } | 356 } |
323 if (!is_write) { | 357 if (!is_write) { |
324 mov_ir(code, size == SZ_B ? 0xFF : 0xFFFF, opts->scratch1, size); | 358 mov_ir(code, size == SZ_B ? 0xFF : 0xFFFF, opts->scratch1, size); |
325 } | 359 } |