Kaynağa Gözat

Fix MMU mirroring algo, support reading 48 KB ROMs.

master
Ben Kurtovic 9 yıl önce
ebeveyn
işleme
9397107e21
4 değiştirilmiş dosya ile 29 ekleme ve 28 silme
  1. +3
    -3
      src/assembler.c
  2. +17
    -4
      src/mmu.c
  3. +8
    -20
      src/rom.c
  4. +1
    -1
      src/util.c

+ 3
- 3
src/assembler.c Dosyayı Görüntüle

@@ -91,7 +91,7 @@ static ErrorInfo* check_layout(
{
const ASMLine *clash = NULL;

if (loc->offset + loc->length >= size) {
if (loc->offset + loc->length > size) {
clash = &bounds_sentinel;
} else {
for (size_t i = 0; i < loc->length; i++) {
@@ -226,7 +226,7 @@ static ErrorInfo* resolve_defaults(AssemblerState *state)
const ASMInstruction *inst = state->instructions;
while (inst) {
size_t bound = inst->loc.offset + inst->loc.length;
if (bound >= state->rom_size)
if (bound > state->rom_size)
state->rom_size = bounding_rom_size(bound);
inst = inst->next;
}
@@ -234,7 +234,7 @@ static ErrorInfo* resolve_defaults(AssemblerState *state)
const ASMData *data = state->data;
while (data) {
size_t bound = data->loc.offset + data->loc.length;
if (bound >= state->rom_size)
if (bound > state->rom_size)
state->rom_size = bounding_rom_size(bound);
data = data->next;
}


+ 17
- 4
src/mmu.c Dosyayı Görüntüle

@@ -52,15 +52,28 @@ void mmu_load_rom(MMU *mmu, const uint8_t *data, size_t size)
if (size % MMU_ROM_BANK_SIZE)
return;

size_t banks = size / MMU_ROM_BANK_SIZE;
size_t banks = size / MMU_ROM_BANK_SIZE, bank, mirror;
if (banks > MMU_NUM_ROM_BANKS)
banks = MMU_NUM_ROM_BANKS;

for (size_t bank = 0; bank < banks; bank++) {
for (size_t mirror = bank; mirror < banks; mirror += bank + 1) {
for (bank = 0; bank < banks; bank++) {
for (mirror = bank; mirror < MMU_NUM_ROM_BANKS; mirror += banks)
mmu->rom_banks[mirror] = data + (bank * MMU_ROM_BANK_SIZE);
}

#ifdef DEBUG_MODE
char temp_str[64];
DEBUG("Dumping MMU bank table:")
for (size_t group = 0; group < MMU_NUM_ROM_BANKS / 8; group++) {
for (size_t elem = 0; elem < 8; elem++) {
bank = 8 * group + elem;
snprintf(temp_str + 6 * elem, 7, "%02zX=%02zX ", bank,
(mmu->rom_banks[bank] - data) >> 14);
}
temp_str[47] = '\0';
DEBUG("- %s", temp_str)
}
#endif
}

/*
@@ -68,7 +81,7 @@ void mmu_load_rom(MMU *mmu, const uint8_t *data, size_t size)
*/
static inline void map_slot(MMU *mmu, size_t slot, size_t bank)
{
DEBUG("MMU mapping memory slot %zu to bank %zu", slot, bank)
DEBUG("MMU mapping memory slot %zu to bank 0x%02zX", slot, bank)
mmu->map_slots[slot] = mmu->rom_banks[bank];
}



+ 8
- 20
src/rom.c Dosyayı Görüntüle

@@ -20,18 +20,6 @@
static size_t header_locations[NUM_LOCATIONS] = {0x7FF0, 0x3FF0, 0x1FF0};
static const char header_magic[MAGIC_LEN + 1] = "TMR SEGA";

/*
Return whether or not the given ROM image size is valid.
*/
static bool validate_size(off_t size)
{
if (size & (size - 1))
return false; // Ensure size is a power of two

off_t kbytes = size >> 10;
return kbytes >= 8 && kbytes <= 1024;
}

#ifdef DEBUG_MODE
/*
DEBUG FUNCTION: Print out the header to stdout.
@@ -96,15 +84,14 @@ static uint16_t compute_checksum(const uint8_t *data, size_t size, uint8_t range

#ifdef DEBUG_MODE
/*
DEBUG FUNCTION: Return the ROM's size as a string, according to its header.
DEBUG FUNCTION: Given a ROM size, return a pretty string.
*/
static const char* parse_reported_size(uint8_t value)
static const char* size_to_string(size_t size)
{
static char buffer[SIZE_CODE_BUF];
size_t size = size_code_to_bytes(value);

if (!size)
strncpy(buffer, "Unknown", SIZE_CODE_BUF);
strncpy(buffer, "unknown", SIZE_CODE_BUF);
else if (size >= (1 << 20))
snprintf(buffer, SIZE_CODE_BUF, "%zu MB", size >> 20);
else
@@ -162,7 +149,8 @@ static bool parse_header(ROM *rom, const uint8_t *header)
DEBUG(" - version: %u", rom->version)
DEBUG(" - region code: %u (%s)", rom->region_code,
rom_region(rom) ? rom_region(rom) : "unknown")
DEBUG(" - reported size: %s", parse_reported_size(header[0xF] & 0xF))
DEBUG(" - reported size: %s",
size_to_string(size_code_to_bytes(header[0xF] & 0xF)))
return true;
}

@@ -191,7 +179,7 @@ static bool find_and_read_header(ROM *rom)
return parse_header(rom, header);
}
}
DEBUG(" - could not find header")
DEBUG(" - couldn't find header")
return false;
}

@@ -240,8 +228,8 @@ const char* rom_open(ROM **rom_ptr, const char *path)
DEBUG("Loading ROM %s:", rom->name)

// Set rom->size:
DEBUG("- size: %lld", st.st_size)
if (!validate_size(st.st_size)) {
DEBUG("- size: %lld bytes (%s)", st.st_size, size_to_string(st.st_size))
if (size_bytes_to_code(st.st_size) == INVALID_SIZE_CODE) {
rom_close(rom);
fclose(fp);
return rom_err_badsize;


+ 1
- 1
src/util.c Dosyayı Görüntüle

@@ -126,7 +126,7 @@ size_t size_code_to_bytes(uint8_t code)
uint8_t size_bytes_to_code(size_t bytes)
{
if (bytes & ((1 << 10) - 1))
return 0; // Not an even number of KB
return INVALID_SIZE_CODE; // Not an even number of KB

switch (bytes >> 10) {
case 8: return 0xA;


Yükleniyor…
İptal
Kaydet