Mercurial > repos > blastem
diff 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 |
line wrap: on
line diff
--- a/backend_x86.c Sat Jan 15 13:15:21 2022 -0800 +++ b/backend_x86.c Tue Jan 18 00:03:50 2022 -0800 @@ -116,7 +116,7 @@ if (after_inc) { *after_inc = code->cur; } - + if (opts->address_size == SZ_D && opts->address_mask != 0xFFFFFFFF) { and_ir(code, opts->address_mask, adr_reg, SZ_D); } else if (opts->address_size == SZ_W && opts->address_mask != 0xFFFF) { @@ -127,19 +127,31 @@ uint32_t ram_flags_off = opts->ram_flags_off; uint32_t min_address = 0; uint32_t max_address = opts->max_address; + uint8_t need_wide_jcc = 0; for (uint32_t chunk = 0; chunk < num_chunks; chunk++) { + code_info chunk_start = *code; if (memmap[chunk].start > min_address) { cmp_ir(code, memmap[chunk].start, adr_reg, opts->address_size); lb_jcc = code->cur + 1; - jcc(code, CC_C, code->cur + 2); + if (need_wide_jcc) { + jcc(code, CC_C, code->cur + 130); + lb_jcc++; + } else { + jcc(code, CC_C, code->cur + 2); + } } else { min_address = memmap[chunk].end; } if (memmap[chunk].end < max_address) { cmp_ir(code, memmap[chunk].end, adr_reg, opts->address_size); ub_jcc = code->cur + 1; - jcc(code, CC_NC, code->cur + 2); + if (need_wide_jcc) { + jcc(code, CC_NC, code->cur + 130); + ub_jcc++; + } else { + jcc(code, CC_NC, code->cur + 2); + } } else { max_address = memmap[chunk].start; } @@ -312,13 +324,35 @@ } } if (lb_jcc) { - *lb_jcc = code->cur - (lb_jcc+1); + if (need_wide_jcc) { + *((int32_t*)lb_jcc) = code->cur - (lb_jcc+4); + } else if (code->cur - (lb_jcc+1) > 0x7f) { + need_wide_jcc = 1; + chunk--; + *code = chunk_start; + continue; + } else { + *lb_jcc = code->cur - (lb_jcc+1); + } lb_jcc = NULL; } if (ub_jcc) { - *ub_jcc = code->cur - (ub_jcc+1); + if (need_wide_jcc) { + *((int32_t*)ub_jcc) = code->cur - (ub_jcc+4); + } else if (code->cur - (ub_jcc+1) > 0x7f) { + need_wide_jcc = 1; + chunk--; + *code = chunk_start; + continue; + } else { + *ub_jcc = code->cur - (ub_jcc+1); + } + ub_jcc = NULL; } + if (need_wide_jcc) { + need_wide_jcc = 0; + } } if (!is_write) { mov_ir(code, size == SZ_B ? 0xFF : 0xFFFF, opts->scratch1, size);