summaryrefslogtreecommitdiff
path: root/src/satmkboot.c
diff options
context:
space:
mode:
authorBobby Bingham <koorogi@koorogi.info>2015-09-12 13:51:55 -0500
committerBobby Bingham <koorogi@koorogi.info>2015-09-15 22:43:33 -0500
commitd30a6525d237105ff77e0728fd7378cc674701a3 (patch)
treeb7d9c32afd96a0bc1a3f41522c7cb505dd0c202f /src/satmkboot.c
parent69c9abb0f6726dc84c6d2eb8d127d65755340e52 (diff)
rename bins
Diffstat (limited to 'src/satmkboot.c')
-rw-r--r--src/satmkboot.c277
1 files changed, 0 insertions, 277 deletions
diff --git a/src/satmkboot.c b/src/satmkboot.c
deleted file mode 100644
index 63e7bb6..0000000
--- a/src/satmkboot.c
+++ /dev/null
@@ -1,277 +0,0 @@
-#include <errno.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-
-#include "bootinfo.h"
-#include "symbols.h"
-
-static struct systemid sysid = {
- .magic = "SEGA SEGASATURN ",
- .maker = "SEGA TP T-000 ",
- .product = "T-000000G ",
- .version = "V0.001",
- .reldate = "20000101",
- .device = "CD-1/1 ",
- .regions = "JTUBKAEL ",
- .peripherals = "J ",
- .padding1 = " ",
- .title = "TEST TITLE ",
- .bootsize = 0xe00,
- .stack_master = 0,
- .stack_slave = 0,
- .load_addr = 0x06004000,
- .load_size = 0,
-};
-
-static char ipbuf[0x7200];
-static char *ipfile, *outfile;
-
-static void serialize_region_code(char *out, const struct symbolname *region)
-{
- static const char defcode[32] = "\xa0\x0e\x00\x09" "For ";
- size_t namelen = region ? strlen(region->name) : 0;
-
- memcpy(out, defcode, sizeof defcode);
- if (namelen) memcpy(out+8, region->name, namelen);
- out[8+namelen] = '.';
-}
-
-#define WRITE(f,p,s) fwrite(p,s,1,f)
-#define WRITE32(f,v) fwrite((char[]){(v)>>24,(v)>>16,(v)>>8,(v)},4,1,f)
-
-static int write_output(FILE *fp)
-{
- extern const unsigned char securitycode[];
- extern const size_t securitycode_size;
-
- /* system id - 0x100 bytes */
- WRITE (fp, &sysid, offsetof(struct systemid, bootsize));
- WRITE32(fp, sysid.bootsize);
- WRITE32(fp, 0); /* reserved bytes */
- WRITE32(fp, sysid.stack_master);
- WRITE32(fp, sysid.stack_slave);
- WRITE32(fp, sysid.load_addr);
- WRITE32(fp, sysid.load_size);
- WRITE32(fp, 0); /* reserved bytes */
- WRITE32(fp, 0); /* reserved bytes */
-
- /* security code */
- WRITE(fp, securitycode, securitycode_size);
-
- /* initial program */
- WRITE(fp, ipbuf, sysid.bootsize - 0xe00);
- return ferror(fp) ? -1 : 0;
-}
-
-static size_t default_ip(char *out)
-{
- size_t size = 0;
-
- out[size++] = 0xd0; /* mov.l addr, r0 */
- out[size++] = 0x01;
- out[size++] = 0x40; /* jmp @r0 */
- out[size++] = 0x2b;
- out[size++] = 0x00; /* nop */
- out[size++] = 0x09;
- out[size++] = 0x00; /* nop */
- out[size++] = 0x09;
- out[size++] = sysid.load_addr >> 24 & 0xff; /* addr: .long <sysid.load_addr> */
- out[size++] = sysid.load_addr >> 16 & 0xff;
- out[size++] = sysid.load_addr >> 8 & 0xff;
- out[size++] = sysid.load_addr >> 0 & 0xff;
-
- return size;
-}
-
-static size_t load_ip(char *filename, char *out, size_t maxsize)
-{
- FILE *fp;
- size_t size;
- const char *errprefix = "Error loading initial program";
-
- if (!(fp = fopen(filename, "rb"))) {
- goto fail_perror;
- }
- if ((size = fread(out, 1, maxsize, fp)) < maxsize) {
- /* read fewer than requested amount. determine if we hit error or eof */
- if (ferror(fp)) {
- goto fail_perror;
- }
- } else {
- /* successfully read the requested amount. verify we reached eof */
- if (fgetc(fp) != EOF) {
- fprintf(stderr, "%s: exceeds maximum size\n", errprefix);
- goto fail;
- }
- }
-
- fclose(fp);
- return size;
-
-fail_perror:
- perror(errprefix);
-fail:
- if (fp) fclose(fp);
- return -1;
-}
-
-static void print_symbols(int width, const struct symbolname *symbols)
-{
- for (; symbols->symbol; symbols++) {
- printf("\t%*s%c: %s\n", width+4, "", symbols->symbol, symbols->name);
- }
-}
-
-static void usage(const char *progname)
-{
- const int width = 20;
-
- printf("usage: %s -h\n", progname);
- printf(" %s -o[iprms]\n\n", progname);
- printf("\t%-*s%s\n", width, "-h", "Show this help text");
- printf("\t%-*s%s\n", width, "-o output", "Output file");
- printf("\t%-*s%s\n", width, "-i ip.bin", "Initial program code file");
- printf("\t%-*s%s\n", width, "-p peripherals", "Supported peripherals (default: control pad):");
- print_symbols(width, peripheraldefs);
- printf("\t%-*s%s\n", width, "-r regions", "Geographical regions (default: all):");
- print_symbols(width, regiondefs);
- printf("\t%-*s%s\n", width, "-m master_stack", "Master stack address (default 0x06002000)");
- printf("\t%-*s%s\n", width, "-s slave_stack", "Slave stack address (default 0x06001000)");
-
- exit(0);
-}
-
-static int process_symbols(const char *progname, char *list, size_t size, const char *arg)
-{
- while (size-- && *arg) *list++ = *arg++;
- while (size--) *list++ = ' ';
- return *arg;
-}
-
-static int process_address(const char *progname, uint32_t *addr, const char *arg)
-{
- char *end;
- errno = 0;
- unsigned long val = strtoul(arg, &end, 16);
- if (end == arg || *end || errno || val > (uint32_t)-1) return 1;
- *addr = val;
- return 0;
-}
-
-#define FLAG_o (1U << 3)
-
-static int process_args(int argc, char **argv)
-{
- uint32_t seen = 0;
- int opt, fail = 0;
-
- extern char *optarg;
- extern int optind, optopt;
- static const char *optpat = "hi:o:p:r:m:s:";
- while ((opt = getopt(argc, argv, optpat)) != -1) {
- uint32_t flag = opt == '?' ? 0 : 1U << strchr(optpat, opt) - optpat;
- if (seen & flag) {
- fprintf(stderr, "%s: Duplicate option -%c\n", argv[0], opt);
- fail = 1;
- continue;
- }
- seen |= flag;
-
- switch (opt) {
- case 'h':
- usage(argv[0]);
-
- case 'i':
- ipfile = optarg;
- break;
-
- case 'o':
- outfile = optarg;
- break;
-
- case 'm':
- if (process_address(argv[0], &sysid.stack_master, optarg)) {
- fprintf(stderr, "%s: Invalid master stack\n", argv[0]);
- fail = 1;
- }
- break;
-
- case 's':
- if (process_address(argv[0], &sysid.stack_slave, optarg)) {
- fprintf(stderr, "%s: Invalid slave stack\n", argv[0]);
- fail = 1;
- }
- break;
-
- case 'p':
- if (process_symbols(argv[0], sysid.peripherals, sizeof sysid.peripherals, optarg)) {
- fprintf(stderr, "%s: Too many peripherals specified (max 16)\n", argv[0]);
- fail = 1;
- }
- break;
-
- case 'r':
- if (process_symbols(argv[0], sysid.regions, sizeof sysid.regions, optarg)) {
- fprintf(stderr, "%s: Too many regions specified (max 10)\n", argv[0]);
- fail = 1;
- }
- break;
-
- default:
- fail = 1;
- }
- }
-
- if (!(seen & FLAG_o)) {
- fprintf(stderr, "%s: Missing required option -o\n", argv[0]);
- fail = 1;
- }
- if (argv[optind]) {
- fprintf(stderr, "%s: Unknown option '%s'\n", argv[0], argv[optind]);
- fail = 1;
- }
- if (fail) fprintf(stderr, "\nUse -h option for help on correct usage.\n");
-
- return fail;
-}
-
-int main(int argc, char **argv)
-{
- FILE *outfp = NULL;
- char *ipout = ipbuf;
- size_t ipsize;
-
- if (process_args(argc, argv)) return 1;
-
- for (int i = 0; i < 8; i++) {
- serialize_region_code(ipout, find_symbol(regiondefs, sysid.regions[i]));
- ipout += 32;
- sysid.bootsize += 32;
- }
-
- ipsize = ipfile
- ? load_ip(ipfile, ipout, sizeof ipbuf - (ipout - ipbuf))
- : default_ip(ipout);
- if (ipsize == -1) goto fail;
- sysid.bootsize += ipsize;
-
- if (!(outfp = fopen(outfile, "wb"))) {
- perror("Error opening output file");
- goto fail;
- }
-
- if (write_output(outfp)) {
- perror("Error writing output");
- goto fail;
- }
-
- fclose(outfp);
- return 0;
-
-fail:
- if (outfp) fclose(outfp);
- return 1;
-}