Mercurial > repos > blastem
changeset 2668:b0b6c6042103
Fix some bugs in memory access functions used in interpreter mode
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Sat, 08 Mar 2025 11:45:25 -0800 |
parents | 1f6503bcb1d5 |
children | c6bc66b16392 |
files | backend.c |
diffstat | 1 files changed, 72 insertions(+), 52 deletions(-) [+] |
line wrap: on
line diff
--- a/backend.c Fri Mar 07 23:41:42 2025 -0800 +++ b/backend.c Sat Mar 08 11:45:25 2025 -0800 @@ -162,6 +162,11 @@ return 0xFFFF; } uint32_t offset = address & chunk->mask; + if (chunk->shift > 0) { + offset <<= chunk->shift; + } else if (chunk->shift < 0){ + offset >>= -chunk->shift; + } if (chunk->flags & MMAP_READ) { uint8_t *base; if (chunk->flags & MMAP_PTR_IDX) { @@ -171,11 +176,6 @@ } if (base) { uint16_t val; - if (chunk->shift > 0) { - offset <<= chunk->shift; - } else if (chunk->shift < 0){ - offset >>= chunk->shift; - } if ((chunk->flags & MMAP_ONLY_ODD) || (chunk->flags & MMAP_ONLY_EVEN)) { offset /= 2; val = base[offset]; @@ -203,6 +203,11 @@ return; } uint32_t offset = address & chunk->mask; + if (chunk->shift > 0) { + offset <<= chunk->shift; + } else if (chunk->shift < 0){ + offset >>= -chunk->shift; + } if (chunk->flags & MMAP_WRITE) { uint8_t *base; if (chunk->flags & MMAP_PTR_IDX) { @@ -211,11 +216,6 @@ base = chunk->buffer; } if (base) { - if (chunk->shift > 0) { - offset <<= chunk->shift; - } else if (chunk->shift < 0){ - offset >>= chunk->shift; - } if ((chunk->flags & MMAP_ONLY_ODD) || (chunk->flags & MMAP_ONLY_EVEN)) { offset /= 2; if (chunk->flags & MMAP_ONLY_EVEN) { @@ -240,6 +240,16 @@ return 0xFF; } uint32_t offset = address & chunk->mask; + if (offset) { + uint32_t low_bit = offset & 1; + offset &= ~1; + if (chunk->shift > 0) { + offset <<= chunk->shift; + } else { + offset >>= -chunk->shift; + } + offset |= low_bit; + } if (chunk->flags & MMAP_READ) { uint8_t *base; if (chunk->flags & MMAP_PTR_IDX) { @@ -248,11 +258,6 @@ base = chunk->buffer; } if (base) { - if (chunk->shift > 0) { - offset <<= chunk->shift; - } else if (chunk->shift < 0){ - offset >>= chunk->shift; - } if ((chunk->flags & MMAP_ONLY_ODD) || (chunk->flags & MMAP_ONLY_EVEN)) { if (address & 1) { if (chunk->flags & MMAP_ONLY_EVEN) { @@ -281,6 +286,16 @@ return; } uint32_t offset = address & chunk->mask; + if (chunk->shift) { + uint32_t low_bit = offset & 1; + offset &= ~1; + if (chunk->shift > 0) { + offset <<= chunk->shift; + } else { + offset >>= -chunk->shift; + } + offset |= low_bit; + } if (chunk->flags & MMAP_WRITE) { uint8_t *base; if (chunk->flags & MMAP_PTR_IDX) { @@ -289,11 +304,6 @@ base = chunk->buffer; } if (base) { - if (chunk->shift > 0) { - offset <<= chunk->shift; - } else if (chunk->shift < 0){ - offset >>= chunk->shift; - } if ((chunk->flags & MMAP_ONLY_ODD) || (chunk->flags & MMAP_ONLY_EVEN)) { if (address & 1) { if (chunk->flags & MMAP_ONLY_EVEN) { @@ -421,6 +431,11 @@ } } uint32_t offset = address & chunk->mask; + if (chunk->shift > 0) { + offset <<= chunk->shift; + } else if (chunk->shift < 0){ + offset >>= -chunk->shift; + } if (chunk->flags & MMAP_READ) { uint8_t *base; if (chunk->flags & MMAP_PTR_IDX) { @@ -431,11 +446,6 @@ } if (base) { uint16_t val; - if (chunk->shift > 0) { - offset <<= chunk->shift; - } else if (chunk->shift < 0){ - offset >>= chunk->shift; - } if ((chunk->flags & MMAP_ONLY_ODD) || (chunk->flags & MMAP_ONLY_EVEN)) { offset /= 2; val = base[offset]; @@ -475,6 +485,16 @@ } } uint32_t offset = address & chunk->mask; + if (chunk->shift) { + uint32_t low_bit = offset & 1; + offset &= ~1; + if (chunk->shift > 0) { + offset <<= chunk->shift; + } else { + offset >>= -chunk->shift; + } + offset |= low_bit; + } if (chunk->flags & MMAP_READ) { uint8_t *base; if (chunk->flags & MMAP_PTR_IDX) { @@ -484,11 +504,6 @@ base = chunk->buffer; } if (base) { - if (chunk->shift > 0) { - offset <<= chunk->shift; - } else if (chunk->shift < 0){ - offset >>= chunk->shift; - } if ((chunk->flags & MMAP_ONLY_ODD) || (chunk->flags & MMAP_ONLY_EVEN)) { if (address & 1) { if (chunk->flags & MMAP_ONLY_EVEN) { @@ -527,7 +542,12 @@ return; } } - uint32_t offset = address & chunk->mask; + uint32_t offset = address & chunk->mask; + if (chunk->shift > 0) { + offset <<= chunk->shift; + } else if (chunk->shift < 0){ + offset >>= -chunk->shift; + } if (chunk->flags & MMAP_WRITE) { uint8_t *base; if (chunk->flags & MMAP_PTR_IDX) { @@ -537,11 +557,6 @@ base = chunk->buffer; } if (base) { - if (chunk->shift > 0) { - offset <<= chunk->shift; - } else if (chunk->shift < 0){ - offset >>= chunk->shift; - } if ((chunk->flags & MMAP_ONLY_ODD) || (chunk->flags & MMAP_ONLY_EVEN)) { offset /= 2; if (chunk->flags & MMAP_ONLY_EVEN) { @@ -577,6 +592,16 @@ } } uint32_t offset = address & chunk->mask; + if (chunk->shift) { + uint32_t low_bit = offset & 1; + offset &= ~1; + if (chunk->shift > 0) { + offset <<= chunk->shift; + } else { + offset >>= -chunk->shift; + } + offset |= low_bit; + } if (chunk->flags & MMAP_WRITE) { uint8_t *base; if (chunk->flags & MMAP_PTR_IDX) { @@ -586,11 +611,6 @@ base = chunk->buffer; } if (base) { - if (chunk->shift > 0) { - offset <<= chunk->shift; - } else if (chunk->shift < 0){ - offset >>= chunk->shift; - } if ((chunk->flags & MMAP_ONLY_ODD) || (chunk->flags & MMAP_ONLY_EVEN)) { if (address & 1) { if (chunk->flags & MMAP_ONLY_EVEN) { @@ -624,11 +644,11 @@ *data_out = (void *)(uintptr_t)0xFFFF; return interp_read_fixed_16; } - if (chunk->end < end || chunk->start > start) { + if (chunk->end < end || chunk->start > start || chunk->shift) { goto use_map; } if (chunk->flags & MMAP_READ) { - if ((chunk->flags & (MMAP_ONLY_ODD|MMAP_ONLY_EVEN|MMAP_FUNC_NULL)) || chunk->shift) { + if ((chunk->flags & (MMAP_ONLY_ODD|MMAP_ONLY_EVEN|MMAP_FUNC_NULL))) { goto use_map; } if (!chunk->mask && !(chunk->flags & ~MMAP_READ)) { @@ -674,11 +694,11 @@ *data_out = (void *)(uintptr_t)0xFFFF; return interp_read_fixed_8; } - if (chunk->end != end || chunk->start != start) { + if (chunk->end != end || chunk->start != start || chunk->shift) { goto use_map; } if (chunk->flags & MMAP_READ) { - if ((chunk->flags & (MMAP_ONLY_ODD|MMAP_ONLY_EVEN|MMAP_FUNC_NULL)) || chunk->shift) { + if ((chunk->flags & (MMAP_ONLY_ODD|MMAP_ONLY_EVEN|MMAP_FUNC_NULL)) || !opts->byte_swap) { goto use_map; } if (!chunk->mask && !(chunk->flags & ~MMAP_READ)) { @@ -724,11 +744,11 @@ *data_out = NULL; return interp_write_ignored_16; } - if (chunk->end != end || chunk->start != start) { + if (chunk->end != end || chunk->start != start || chunk->shift) { goto use_map; } - if (chunk->flags & MMAP_READ) { - if ((chunk->flags & (MMAP_ONLY_ODD|MMAP_ONLY_EVEN|MMAP_FUNC_NULL)) || chunk->shift || (chunk->mask & 0xFFFF) != 0xFFFF) { + if (chunk->flags & MMAP_WRITE) { + if ((chunk->flags & (MMAP_ONLY_ODD|MMAP_ONLY_EVEN|MMAP_FUNC_NULL)) || (chunk->mask & 0xFFFF) != 0xFFFF) { goto use_map; } if (chunk->flags & MMAP_PTR_IDX) { @@ -766,11 +786,11 @@ *data_out = NULL; return interp_write_ignored_8; } - if (chunk->end != end || chunk->start != start) { + if (chunk->end != end || chunk->start != start || chunk->shift) { goto use_map; } - if (chunk->flags & MMAP_READ) { - if ((chunk->flags & (MMAP_ONLY_ODD|MMAP_ONLY_EVEN|MMAP_FUNC_NULL)) || chunk->shift + if (chunk->flags & MMAP_WRITE) { + if ((chunk->flags & (MMAP_ONLY_ODD|MMAP_ONLY_EVEN|MMAP_FUNC_NULL)) || (chunk->mask & 0xFFFF) != 0xFFFF || !opts->byte_swap ) { goto use_map; @@ -786,7 +806,7 @@ return interp_write_direct_8; } } - if (chunk->write_16 && chunk->mask == opts->address_mask) { + if (chunk->write_8 && chunk->mask == opts->address_mask) { *data_out = NULL; //This is not safe for all calling conventions due to the extra param //but should work for the ones we actually care about