Browse Source

Implement parsing header size directive.

master
Ben Kurtovic 9 years ago
parent
commit
b174ddd121
5 changed files with 92 additions and 18 deletions
  1. +1
    -1
      src/assembler.c
  2. +26
    -5
      src/assembler/preprocessor.c
  3. +12
    -12
      src/rom.c
  4. +51
    -0
      src/util.c
  5. +2
    -0
      src/util.h

+ 1
- 1
src/assembler.c View File

@@ -44,7 +44,7 @@ static ErrorInfo* resolve_defaults(AssemblerState *state)
// check reported rom size is <= actual rom size

// if (!state.header.rom_size)
// set to actual rom size
// set to actual rom size using util's size_bytes_to_code()

(void) state;
return NULL;


+ 26
- 5
src/assembler/preprocessor.c View File

@@ -306,6 +306,14 @@ static ErrorInfo* build_asm_lines(
}

/*
Return whether the given header offset is a valid location.
*/
static inline bool is_header_offset_valid(uint16_t offset)
{
return offset == 0x7FF0 || offset == 0x3FF0 || offset == 0x1FF0;
}

/*
Parse the region code string in an ASMLine and store it in *result.

Return true on success and false on failure; in the latter case, *result is
@@ -334,11 +342,20 @@ static bool parse_region_string(uint8_t *result, const ASMLine *line)
}

/*
Return whether the given header offset is a valid location.
Parse the size code in an ASMLine and store it in *result.

Return true on success and false on failure.
*/
static inline bool is_header_offset_valid(uint16_t offset)
static bool parse_size_code(uint8_t *result, const ASMLine *line)
{
return offset == 0x7FF0 || offset == 0x3FF0 || offset == 0x1FF0;
uint32_t bytes;
if (!parse_uint32_t(&bytes, line, DIR_ROM_DECLSIZE))
return false;

uint8_t code = size_bytes_to_code(bytes);
if (code)
return (*result = code), true;
return false;
}

/*
@@ -417,8 +434,12 @@ ErrorInfo* preprocess(AssemblerState *state, const LineBuffer *source)
END_DIRECTIVE

BEGIN_DIRECTIVE(DIR_ROM_DECLSIZE, uint8_t, state->header.rom_size, 0)
// TODO: fixme
FAIL(ED_PP_UNKNOWN)
PARSER_BRANCH(uint8_t, {
CLAMP_RANGE(0x10)
VALIDATE(size_code_to_bytes(arg))
}, {
VALIDATE(parse_size_code(&arg, line))
})
END_DIRECTIVE

END_DIRECTIVE_BLOCK


+ 12
- 12
src/rom.c View File

@@ -16,6 +16,7 @@
#define NUM_LOCATIONS 3
#define MAGIC_LEN 8
#define HEADER_SIZE 16
#define SIZE_CODE_BUF 8

static size_t header_locations[NUM_LOCATIONS] = {0x7FF0, 0x3FF0, 0x1FF0};
static const char header_magic[MAGIC_LEN + 1] = "TMR SEGA";
@@ -100,18 +101,17 @@ static uint16_t compute_checksum(const uint8_t *data, size_t size, uint8_t range
*/
static const char* parse_reported_size(uint8_t value)
{
switch (value) {
case 0xA: return "8 KB";
case 0xB: return "16 KB";
case 0xC: return "32 KB";
case 0xD: return "48 KB";
case 0xE: return "64 KB";
case 0xF: return "128 KB";
case 0x0: return "256 KB";
case 0x1: return "512 KB";
case 0x2: return "1 MB";
default: return "Unknown";
}
static char buffer[SIZE_CODE_BUF];
size_t size = size_code_to_bytes(value);

if (!size)
strncpy(buffer, "Unknown", SIZE_CODE_BUF);
else if (size >= (1 << 20))
snprintf(buffer, SIZE_CODE_BUF, "%zu MB", size >> 20);
else
snprintf(buffer, SIZE_CODE_BUF, "%zu KB", size >> 10);

return buffer;
}
#endif



+ 51
- 0
src/util.c View File

@@ -90,3 +90,54 @@ uint8_t region_string_to_code(const char *name)
}
return 0;
}

/*
Return the number of bytes in a ROM image based on its header size code.

0 is returned if the code is invalid.
*/
size_t size_code_to_bytes(uint8_t code)
{
#define KB << 10
#define MB << 20

switch (code) {
case 0xA: return 8 KB;
case 0xB: return 16 KB;
case 0xC: return 32 KB;
case 0xD: return 48 KB;
case 0xE: return 64 KB;
case 0xF: return 128 KB;
case 0x0: return 256 KB;
case 0x1: return 512 KB;
case 0x2: return 1 MB;
default: return 0;
}

#undef KB
#undef MB
}

/*
Given the number of bytes in a ROM image, return the size code.

0 is returned if the size is invalid.
*/
uint8_t size_bytes_to_code(size_t bytes)
{
if (bytes & ((1 << 10) - 1))
return 0; // Not an even number of KB

switch (bytes >> 10) {
case 8: return 0xA;
case 16: return 0xB;
case 32: return 0xC;
case 48: return 0xD;
case 64: return 0xE;
case 128: return 0xF;
case 256: return 0x0;
case 512: return 0x1;
case 1024: return 0x2;
default: return 0;
}
}

+ 2
- 0
src/util.h View File

@@ -11,3 +11,5 @@ uint8_t bcd_decode(uint8_t);
uint64_t get_time_ns();
const char* region_code_to_string(uint8_t);
uint8_t region_string_to_code(const char*);
size_t size_code_to_bytes(uint8_t);
uint8_t size_bytes_to_code(size_t);

Loading…
Cancel
Save