Last active
January 8, 2022 17:29
-
-
Save PikalaxALT/ce7f64077eb4234a91a8a32c3631a67b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <getopt.h> | |
#include <stdbool.h> | |
#include <stdlib.h> | |
#include <string.h> | |
struct Section { | |
unsigned short end; | |
bool invalid; | |
char * name; | |
bool banked; | |
}; | |
typedef struct Section section_t; | |
size_t strrspn(const char *s1, const char *s2) { | |
const char * _s1 = s1; | |
const char * _s2; | |
while (*_s1++); | |
_s1--; | |
while (_s1 > s1) { | |
for (_s2 = s2; *_s2; _s2++) { | |
if (_s1[-1] == *_s2) { | |
break; | |
} | |
} | |
if (*_s2 == 0) | |
break; | |
_s1--; | |
} | |
return _s1 - s1; | |
} | |
size_t strrcspn(const char *s1, const char *s2) { | |
const char * _s1 = s1; | |
const char * _s2; | |
while (*_s1++); | |
_s1--; | |
while (_s1 > s1) { | |
for (_s2 = s2; *_s2; _s2++) { | |
if (_s1[-1] == *_s2) | |
break; | |
} | |
if (*_s2) | |
break; | |
_s1--; | |
} | |
return _s1 - s1; | |
} | |
int main(int argc, char * argv[]) { | |
int ch; | |
size_t lsize = 0; | |
char * line = NULL; | |
section_t section_list[] = { | |
{0x4000, false, "ROM0", false}, | |
{0x8000, false, "ROMX", true}, | |
{0xA000, false, "VRAM", true}, | |
{0xC000, false, "SRAM", true}, | |
{0xD000, false, "WRAM0", false}, | |
{0xE000, false, "WRAMX", true}, | |
{0xFE00, true, "Echo RAM", false}, | |
{0xFEA0, false, "OAM", false}, | |
{0xFF80, true, "FEXX / IO", false}, | |
{0xFFFF, false, "HRAM", false}, | |
{} | |
}; | |
while ((ch = getopt(argc, argv, "wdt")) != -1) { | |
switch (ch) { | |
case 'w': | |
case 'd': | |
section_list[4].end = 0xE000; | |
break; | |
case 't': | |
section_list[0].end = 0x8000; | |
break; | |
} | |
} | |
for (int arg_idx = optind; arg_idx < argc; arg_idx++) { | |
FILE * file = fopen(argv[arg_idx], "r"); | |
if (file == NULL) { | |
perror("file io"); | |
free(line); | |
return 1; | |
} | |
while (getline(&line, &lsize, file) > 0) { | |
unsigned short bank = 0; | |
unsigned short pointer = 0; | |
char * symbol = NULL; | |
char * end; | |
char * addr_p; | |
// line = line.split(";")[0].strip() | |
line += strspn(line, " \t\n"); | |
end = strchr(line, ';'); | |
if (end) *end = 0; | |
line[strrspn(line, " \t\n")] = 0; | |
if (!*line) | |
continue; | |
// Get the bank, address, and symbol | |
end = line + strcspn(line, " \t\n"); | |
symbol = end + strspn(end, " \t\n"); | |
if (!*symbol) { | |
perror("parse"); | |
free(line); | |
fclose(file); | |
return 1; | |
} | |
*end = 0; | |
addr_p = strchr(line, ':'); | |
if (!addr_p) { | |
perror("parse"); | |
free(line); | |
fclose(file); | |
return 1; | |
} | |
*addr_p++ = 0; | |
pointer = strtoul(addr_p, &end, 16); | |
if (pointer == 0 && end == addr_p) { | |
perror("parse"); | |
free(line); | |
fclose(file); | |
return 1; | |
} | |
bank = strtoul(line, &end, 16); | |
if (bank == 0 && end == line) { | |
perror("parse"); | |
free(line); | |
fclose(file); | |
return 1; | |
} | |
// Main loop | |
const char * section = NULL; | |
section_t * section_type; | |
for (section_type = section_list; section_type->end; section_type++) { | |
if (pointer < section_type->end) { | |
if (section_type->invalid) { | |
fprintf(stderr, "Warning: cannot shim '%s' in section type '%s'\n", symbol, section_type->name); | |
} else { | |
section = section_type->name; | |
if (!section_type->banked) | |
bank = 0; | |
} | |
break; | |
} | |
} | |
if (section == NULL) | |
// Found section, but cannot shim it | |
continue; | |
printf("SECTION \"Shim for %s\", %s[$%04X]", symbol, section, pointer); | |
if (bank) | |
printf(", BANK[$%04X]", bank); | |
printf("\n%s::\n\n", symbol); | |
fflush(stdout); | |
} | |
fclose(file); | |
} | |
free(line); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment