From a3e01367f11a99aac5dc06c64178aa2bd946ac8b Mon Sep 17 00:00:00 2001 From: Lukas Krickl Date: Wed, 13 Mar 2024 06:46:07 +0100 Subject: [PATCH] Added basic mlb support. TODO: Allow user-defined sections for better label support --- src/main.c | 15 ++++++++-- src/ulas.c | 87 ++++++++++++++++++++++++++++++++++++++++++++---------- src/ulas.h | 4 +++ 3 files changed, 89 insertions(+), 17 deletions(-) diff --git a/src/main.c b/src/main.c index fff1c6e..d2a0212 100644 --- a/src/main.c +++ b/src/main.c @@ -23,7 +23,7 @@ #define ULAS_OPTS "hvVpdA" // args with value -#define ULAS_OPTS_ARG "o:l:s:i:w:a:" +#define ULAS_OPTS_ARG "o:l:s:i:w:a:S:" #define ULAS_HELP(a, desc) printf("\t-%s\t%s\n", (a), desc); @@ -34,7 +34,7 @@ unsigned long incpathslen = 0; void ulas_help(void) { printf("%s\n", ULAS_NAME); - printf("Usage %s [-%s] [-o=path] [-i=path] [-l=path] [-a=initial-address] " + printf("Usage %s [-%s] [-o=path] [-i=path] [-l=path] [-a=initial-address] [-S=ulas|mlb] " "[input]\n\n", ULAS_NAME, ULAS_OPTS); ULAS_HELP("h", "display this help and exit"); @@ -48,6 +48,7 @@ void ulas_help(void) { ULAS_HELP("a=initial-address", "Initial starting address"); ULAS_HELP("A", "Print addresses in disassembler mode"); ULAS_HELP("d", "Disassemble a file"); + ULAS_HELP("S", "Set the symbol format"); ULAS_HELP("w=warning", "Toggle warnings: a=all, o=overflow"); } @@ -101,6 +102,16 @@ void ulas_getopt(int argc, char **argv, struct ulas_config *cfg) { case 'A': cfg->print_addrs = 1; break; + case 'S': + if (strcmp("ulas", optarg) == 0) { + cfg->sym_fmt = ULAS_SYM_FMT_DEFAULT; + } else if (strcmp("mlb", optarg) == 0) { + cfg->sym_fmt = ULAS_SYM_FMT_MLB; + } else { + printf("Invalid symbol format: %s\n", optarg); + exit(-1); + } + break; case '?': break; default: diff --git a/src/ulas.c b/src/ulas.c index ca7da5a..07c6717 100644 --- a/src/ulas.c +++ b/src/ulas.c @@ -334,29 +334,85 @@ int ulas_symbolset(const char *cname, int scope, struct ulas_tok tok, return rc; } +int ulas_symbolout_mlbloc(FILE *dst, long addr) { + if (addr == -1) { + fprintf(dst, "Unknown:"); + return 0; + } + + // TODO: maybe allow the user to define this by using + // .section and just trust the label location in the source + // is correct + switch (ulas.arch.type) { + case ULAS_ARCH_SM83: + if (addr >= 0x0000 && addr <= 0x7FFF) { + fprintf(dst, "GbPrgRom:"); + return 0; + } else if (addr >= 0xC000 && addr <= 0xDFFF) { + fprintf(dst, "GbWorkRam:"); + return 0xC000; + } else { + fprintf(dst, "Unknown:"); + return 0; + } + break; + } + return 0; +} + int ulas_symbolout(FILE *dst, struct ulas_sym *s) { if (!dst || ulas.pass != ULAS_PASS_FINAL) { return 0; } int rc = 0; - if (!s->name || s->name[0] == '\0') { - fprintf(dst, " = "); - } else { - fprintf(dst, "%s = ", s->name); - } - switch (s->tok.type) { - case ULAS_INT: - fprintf(dst, "0x%x", ulas_valint(&s->tok, &rc)); - break; - case ULAS_STR: - fprintf(dst, "%s", ulas_valstr(&s->tok, &rc)); + + switch (ulascfg.sym_fmt) { + case ULAS_SYM_FMT_DEFAULT: + if (!s->name || s->name[0] == '\0') { + fprintf(dst, " = "); + } else { + fprintf(dst, "%s = ", s->name); + } + switch (s->tok.type) { + case ULAS_INT: + fprintf(dst, "0x%x", ulas_valint(&s->tok, &rc)); + break; + case ULAS_STR: + fprintf(dst, "%s", ulas_valstr(&s->tok, &rc)); + break; + default: + fprintf(dst, ""); + break; + } + fprintf(dst, "\n"); break; - default: - fprintf(dst, ""); + case ULAS_SYM_FMT_MLB: + switch (s->tok.type) { + case ULAS_INT: { + int valint = ulas_valint(&s->tok, &rc); + valint -= ulas_symbolout_mlbloc(dst, valint); + fprintf(dst, "%x:", valint); + break; + } + case ULAS_STR: + ulas_symbolout_mlbloc(dst, -1); + fprintf(dst, "%s:", ulas_valstr(&s->tok, &rc)); + break; + default: + ulas_symbolout_mlbloc(dst, -1); + fprintf(dst, ":"); + break; + } + if (!s->name || s->name[0] == '\0') { + fprintf(dst, ":"); + } else { + fprintf(dst, "%s:%s", s->name, s->name); + } + + fprintf(dst, "\n"); break; } - fprintf(dst, "\n"); return rc; } @@ -376,7 +432,8 @@ int ulas_tok(struct ulas_str *dst, const char **out_line, unsigned long n) { i++; } - // string token + // s + // tring token if (line[i] == '"') { dst->buf[write++] = line[i++]; int last_escape = 0; diff --git a/src/ulas.h b/src/ulas.h index 8c58880..e124ba9 100644 --- a/src/ulas.h +++ b/src/ulas.h @@ -119,6 +119,8 @@ struct ulas_tok; enum ulas_warm { ULAS_WARN_OVERFLOW = 1, ULAS_WARN_ALL = 0x7FFFFFFF }; +enum ulas_symfmt { ULAS_SYM_FMT_DEFAULT, ULAS_SYM_FMT_MLB }; + struct ulas_config { // argv represents file names char **argv; @@ -128,6 +130,8 @@ struct ulas_config { char *lst_path; char *sym_path; + enum ulas_symfmt sym_fmt; + int verbose; int preproc_only; int disas; -- 2.30.2