#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);
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");
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");
}
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:
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, "<unnamed> = ");
- } 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, "<unnamed> = ");
+ } 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, "<Unknown type>");
+ break;
+ }
+ fprintf(dst, "\n");
break;
- default:
- fprintf(dst, "<Unknown type>");
+ 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, "<Unknown type>:");
+ break;
+ }
+ if (!s->name || s->name[0] == '\0') {
+ fprintf(dst, "<unnamed>:<unnamed>");
+ } else {
+ fprintf(dst, "%s:%s", s->name, s->name);
+ }
+
+ fprintf(dst, "\n");
break;
}
- fprintf(dst, "\n");
return rc;
}
i++;
}
- // string token
+ // s
+ // tring token
if (line[i] == '"') {
dst->buf[write++] = line[i++];
int last_escape = 0;