mirror of
https://github.com/zeldaret/oot.git
synced 2024-11-10 19:20:13 +00:00
Add support for 'after' and 'number' in mkldscript and use 'after' to properly shift the code segment (#194)
* Add support for 'after' and 'number' in mkldscript * Use 'after' in spec to ensure code ends up after dmadata in RAM
This commit is contained in:
parent
c10bcdc3c4
commit
e413325637
2 changed files with 39 additions and 24 deletions
2
spec
2
spec
|
@ -268,7 +268,7 @@ endseg
|
||||||
|
|
||||||
beginseg
|
beginseg
|
||||||
name "code"
|
name "code"
|
||||||
address 0x8001CE60
|
after "dmadata"
|
||||||
include "build/src/code/z_en_a_keep.o"
|
include "build/src/code/z_en_a_keep.o"
|
||||||
include "build/src/code/z_en_item00.o"
|
include "build/src/code/z_en_item00.o"
|
||||||
include "build/data/z_en_item00.data.o"
|
include "build/data/z_en_item00.data.o"
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
//#include "opts.h"
|
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
#define ARRAY_COUNT(arr) (sizeof(arr) / sizeof(arr[0]))
|
#define ARRAY_COUNT(arr) (sizeof(arr) / sizeof(arr[0]))
|
||||||
|
@ -16,6 +15,7 @@ static FILE *fout;
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
STMT_address,
|
STMT_address,
|
||||||
|
STMT_after,
|
||||||
STMT_align,
|
STMT_align,
|
||||||
STMT_beginseg,
|
STMT_beginseg,
|
||||||
STMT_endseg,
|
STMT_endseg,
|
||||||
|
@ -23,6 +23,7 @@ enum
|
||||||
STMT_flags,
|
STMT_flags,
|
||||||
STMT_include,
|
STMT_include,
|
||||||
STMT_name,
|
STMT_name,
|
||||||
|
STMT_number,
|
||||||
STMT_romalign,
|
STMT_romalign,
|
||||||
STMT_stack,
|
STMT_stack,
|
||||||
STMT_increment,
|
STMT_increment,
|
||||||
|
@ -39,6 +40,7 @@ struct Segment
|
||||||
{
|
{
|
||||||
uint32_t fields;
|
uint32_t fields;
|
||||||
char *name;
|
char *name;
|
||||||
|
char *after;
|
||||||
uint32_t flags;
|
uint32_t flags;
|
||||||
uint32_t address;
|
uint32_t address;
|
||||||
uint32_t stack;
|
uint32_t stack;
|
||||||
|
@ -46,6 +48,7 @@ struct Segment
|
||||||
uint32_t romalign;
|
uint32_t romalign;
|
||||||
uint32_t increment;
|
uint32_t increment;
|
||||||
uint32_t entry;
|
uint32_t entry;
|
||||||
|
uint32_t number;
|
||||||
char **includes;
|
char **includes;
|
||||||
int includesCount;
|
int includesCount;
|
||||||
};
|
};
|
||||||
|
@ -165,17 +168,19 @@ static bool is_pow_of_2(unsigned int n)
|
||||||
|
|
||||||
static const char *const stmtNames[] =
|
static const char *const stmtNames[] =
|
||||||
{
|
{
|
||||||
[STMT_address] = "address",
|
[STMT_address] = "address",
|
||||||
[STMT_align] = "align",
|
[STMT_after] = "after",
|
||||||
[STMT_beginseg] = "beginseg",
|
[STMT_align] = "align",
|
||||||
[STMT_endseg] = "endseg",
|
[STMT_beginseg] = "beginseg",
|
||||||
[STMT_entry] = "entry",
|
[STMT_endseg] = "endseg",
|
||||||
[STMT_flags] = "flags",
|
[STMT_entry] = "entry",
|
||||||
[STMT_include] = "include",
|
[STMT_flags] = "flags",
|
||||||
[STMT_name] = "name",
|
[STMT_include] = "include",
|
||||||
[STMT_romalign] = "romalign",
|
[STMT_name] = "name",
|
||||||
[STMT_stack] = "stack",
|
[STMT_number] = "number",
|
||||||
[STMT_increment] = "increment",
|
[STMT_romalign] = "romalign",
|
||||||
|
[STMT_stack] = "stack",
|
||||||
|
[STMT_increment] = "increment",
|
||||||
};
|
};
|
||||||
|
|
||||||
static void parse_rom_spec(char *spec)
|
static void parse_rom_spec(char *spec)
|
||||||
|
@ -228,10 +233,18 @@ static void parse_rom_spec(char *spec)
|
||||||
if (!parse_quoted_string(args, &currSeg->name))
|
if (!parse_quoted_string(args, &currSeg->name))
|
||||||
util_fatal_error("line %i: invalid name", lineNum);
|
util_fatal_error("line %i: invalid name", lineNum);
|
||||||
break;
|
break;
|
||||||
|
case STMT_after:
|
||||||
|
if (!parse_quoted_string(args, &currSeg->after))
|
||||||
|
util_fatal_error("line %i: invalid name for 'after'", lineNum);
|
||||||
|
break;
|
||||||
case STMT_address:
|
case STMT_address:
|
||||||
if (!parse_number(args, &currSeg->address))
|
if (!parse_number(args, &currSeg->address))
|
||||||
util_fatal_error("line %i: expected number after 'address'", lineNum);
|
util_fatal_error("line %i: expected number after 'address'", lineNum);
|
||||||
break;
|
break;
|
||||||
|
case STMT_number:
|
||||||
|
if (!parse_number(args, &currSeg->number))
|
||||||
|
util_fatal_error("line %i: expected number after 'number'", lineNum);
|
||||||
|
break;
|
||||||
case STMT_flags:
|
case STMT_flags:
|
||||||
if (!parse_flags(args, &currSeg->flags))
|
if (!parse_flags(args, &currSeg->flags))
|
||||||
util_fatal_error("line %i: invalid flags", lineNum);
|
util_fatal_error("line %i: invalid flags", lineNum);
|
||||||
|
@ -242,23 +255,21 @@ static void parse_rom_spec(char *spec)
|
||||||
if (!is_pow_of_2(currSeg->align))
|
if (!is_pow_of_2(currSeg->align))
|
||||||
util_fatal_error("line %i: alignment is not a power of two", lineNum);
|
util_fatal_error("line %i: alignment is not a power of two", lineNum);
|
||||||
break;
|
break;
|
||||||
case STMT_include:
|
|
||||||
currSeg->includesCount++;
|
|
||||||
currSeg->includes = realloc(currSeg->includes, currSeg->includesCount * sizeof(*currSeg->includes));
|
|
||||||
if (!parse_quoted_string(args, &currSeg->includes[currSeg->includesCount - 1]))
|
|
||||||
util_fatal_error("line %i: invalid filename", lineNum);
|
|
||||||
break;
|
|
||||||
case STMT_romalign:
|
case STMT_romalign:
|
||||||
if (!parse_number(args, &currSeg->romalign))
|
if (!parse_number(args, &currSeg->romalign))
|
||||||
util_fatal_error("line %i: expected number after 'romalign'", lineNum);
|
util_fatal_error("line %i: expected number after 'romalign'", lineNum);
|
||||||
if (!is_pow_of_2(currSeg->romalign))
|
if (!is_pow_of_2(currSeg->romalign))
|
||||||
util_fatal_error("line %i: alignment is not a power of two", lineNum);
|
util_fatal_error("line %i: alignment is not a power of two", lineNum);
|
||||||
break;
|
break;
|
||||||
|
case STMT_include:
|
||||||
|
currSeg->includesCount++;
|
||||||
|
currSeg->includes = realloc(currSeg->includes, currSeg->includesCount * sizeof(*currSeg->includes));
|
||||||
|
if (!parse_quoted_string(args, &currSeg->includes[currSeg->includesCount - 1]))
|
||||||
|
util_fatal_error("line %i: invalid filename", lineNum);
|
||||||
|
break;
|
||||||
case STMT_increment:
|
case STMT_increment:
|
||||||
if (!parse_number(args, &currSeg->increment))
|
if (!parse_number(args, &currSeg->increment))
|
||||||
util_fatal_error("line %i: expected number after 'increment'", lineNum);
|
util_fatal_error("line %i: expected number after 'increment'", lineNum);
|
||||||
//if (!is_pow_of_2(currSeg->romalign))
|
|
||||||
//util_fatal_error("line %i: alignment is not a power of two", lineNum);
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "warning: '%s' is not implemented\n", stmtName);
|
fprintf(stderr, "warning: '%s' is not implemented\n", stmtName);
|
||||||
|
@ -314,10 +325,14 @@ static void write_ld_script(void)
|
||||||
|
|
||||||
fprintf(fout, " _%sSegmentRomStart = _RomSize;\n"
|
fprintf(fout, " _%sSegmentRomStart = _RomSize;\n"
|
||||||
" ..%s ", seg->name, seg->name);
|
" ..%s ", seg->name, seg->name);
|
||||||
if (seg->address != 0)
|
|
||||||
{
|
if (seg->fields & (1 << STMT_after))
|
||||||
|
fprintf(fout, "_%sSegmentEnd ", seg->after);
|
||||||
|
else if (seg->fields & (1 << STMT_number))
|
||||||
|
fprintf(fout, "0x%02X000000 ", seg->number);
|
||||||
|
else if (seg->fields & (1 << STMT_address))
|
||||||
fprintf(fout, "0x%08X ", seg->address);
|
fprintf(fout, "0x%08X ", seg->address);
|
||||||
}
|
|
||||||
// (AT(_RomSize) isn't necessary, but adds useful "load address" lines to the map file)
|
// (AT(_RomSize) isn't necessary, but adds useful "load address" lines to the map file)
|
||||||
fprintf(fout, ": AT(_RomSize)\n {\n"
|
fprintf(fout, ": AT(_RomSize)\n {\n"
|
||||||
" _%sSegmentStart = .;\n"
|
" _%sSegmentStart = .;\n"
|
||||||
|
|
Loading…
Reference in a new issue