Sfoglia il codice sorgente

Work on parsing headers.

master
Ben Kurtovic 9 anni fa
parent
commit
332216b193
3 ha cambiato i file con 82 aggiunte e 10 eliminazioni
  1. +3
    -0
      src/logging.h
  2. +74
    -6
      src/rom.c
  3. +5
    -4
      src/rom.h

+ 3
- 0
src/logging.h Vedi File

@@ -30,6 +30,9 @@
#ifdef DEBUG_MODE
#define DEBUG(...) LOG_MSG("[DEBUG]", {}, {}, __VA_ARGS__)
#define DEBUG_ERRNO(...) LOG_MSG("[DEBUG]", PRINT_ERRNO(), {}, __VA_ARGS__)
#else
#define DEBUG(...) {}
#define DEBUG_ERRNO(...) {}
#endif

#define OUT_OF_MEMORY() FATAL("couldn't allocate enough memory")

+ 74
- 6
src/rom.c Vedi File

@@ -1,6 +1,7 @@
/* Copyright (C) 2014-2015 Ben Kurtovic <ben.kurtovic@gmail.com>
Released under the terms of the MIT License. See LICENSE for details. */

#include <ctype.h>
#include <errno.h>
#include <stdbool.h>
#include <stdio.h>
@@ -11,17 +12,76 @@
#include "rom.h"
#include "logging.h"

#define NUM_LOCATIONS 3
#define MAGIC_LEN 8
#define HEADER_SIZE 16

static size_t header_locations[NUM_LOCATIONS] = {0x7ff0, 0x1ff0, 0x3ff0};
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;
if (kbytes << 10 != size)
return false;
if (kbytes < 8 || kbytes > 1024)
return false;
return !(kbytes & (kbytes - 1));
return kbytes >= 8 && kbytes <= 1024;
}

#ifdef DEBUG_MODE
/*
DEBUG FUNCTION: Print out the header to stdout.
*/
static void print_header(const char *header)
{
char header_hex[3 * HEADER_SIZE], header_chr[3 * HEADER_SIZE];

for (int i = 0; i < HEADER_SIZE; i++) {
snprintf(&header_hex[3 * i], 3, "%02x", header[i]);
if (isprint(header[i]))
snprintf(&header_chr[3 * i], 3, "%2c", header[i]);
else {
header_chr[3 * i] = ' ';
header_chr[3 * i + 1] = '?';
}
header_hex[3 * i + 2] = header_chr[3 * i + 2] = ' ';
}
header_hex[3 * HEADER_SIZE - 1] = header_chr[3 * HEADER_SIZE - 1] = '\0';
DEBUG("- header dump (hex): %s", header_hex)
DEBUG("- header dump (chr): %s", header_chr)
}
#endif

/*
Read a ROM image's header, and return whether or not it is valid.
*/
static bool read_header(ROM *rom)
{
size_t location, i;
const char *header;

DEBUG("- looking for header:")
for (i = 0; i < NUM_LOCATIONS; i++) {
location = header_locations[i];
DEBUG(" - trying location 0x%zx:", location)
header = &rom->data[location];
if (memcmp(header, header_magic, MAGIC_LEN)) {
DEBUG(" - magic not present")
}
else {
DEBUG(" - magic found")
#ifdef DEBUG_MODE
print_header(header);
#endif
// TODO: parse header
return true;
}
}
DEBUG(" - could not find header")
return false;
}

/*
@@ -61,8 +121,10 @@ const char* rom_open(ROM **rom_ptr, const char *path)
if (!(rom->name = malloc(sizeof(char) * (strlen(path) + 1))))
OUT_OF_MEMORY()
strcpy(rom->name, path);
DEBUG("Loading ROM %s:", rom->name)

// Set rom->size:
DEBUG("- size: %lld", st.st_size)
if (!validate_size(st.st_size)) {
rom_close(rom);
fclose(fp);
@@ -78,8 +140,14 @@ const char* rom_open(ROM **rom_ptr, const char *path)
fclose(fp);
return rom_err_badread;
}

fclose(fp);

// Parse the header:
if (!read_header(rom)) {
rom_close(rom);
return rom_err_badheader;
}

*rom_ptr = rom;
return NULL;
}


+ 5
- 4
src/rom.h Vedi File

@@ -5,10 +5,11 @@

/* Error strings */

static const char* rom_err_isdir = "Is a directory";
static const char* rom_err_notfile = "Is not a regular file";
static const char* rom_err_badsize = "Invalid size";
static const char* rom_err_badread = "Couldn't read the entire file";
static const char* rom_err_isdir = "Is a directory";
static const char* rom_err_notfile = "Is not a regular file";
static const char* rom_err_badsize = "Invalid size";
static const char* rom_err_badread = "Couldn't read the entire file";
static const char* rom_err_badheader = "Invalid header";

/* Structs */



Caricamento…
Annulla
Salva