--- generator/main/generator.c 2020/03/04 04:46:43 1.1.1.1 +++ generator/main/generator.c 2020/03/04 04:47:05 1.1.1.3 @@ -16,8 +16,8 @@ #include "ui.h" #include "memz80.h" -#include "mem68k.h" #include "cpu68k.h" +#include "mem68k.h" #include "cpuz80.h" #include "vdp.h" #include "gensound.h" @@ -29,15 +29,20 @@ /*** variables externed in generator.h ***/ unsigned int gen_quit = 0; -unsigned int gen_debugmode = 1; -unsigned int gen_loglevel = 2; /* 2 = NORMAL, 1 = CRITICAL */ +unsigned int gen_debugmode = 0; +unsigned int gen_loglevel = 1; /* 2 = NORMAL, 1 = CRITICAL */ +unsigned int gen_autodetect = 1; /* 0 = no, 1 = yes */ +unsigned int gen_musiclog = 0; /* 0 = no, 1 = GYM, 2 = GNM */ t_cartinfo gen_cartinfo; char gen_leafname[128]; +static int gen_freerom = 0; + /*** forward references ***/ void gen_nicetext(char *out, char *in, unsigned int size); uint16 gen_checksum(uint8 *start, unsigned int length); +void gen_setupcartinfo(void); /*** Signal handler ***/ @@ -47,10 +52,10 @@ RETSIGTYPE gen_sighandler(int signum) if (signum == SIGINT) { if (gen_quit) { LOG_CRITICAL(("Bye!")); - ui_final(); - ui_err("Exiting"); + ui_final(); + ui_err("Exiting"); } else { - LOG_REQUEST(("Ping - current PC = 0x%X", regs.pc)); + LOG_REQUEST(("Ping - current PC = 0x%X", regs.pc)); } gen_quit = 1; } @@ -62,12 +67,13 @@ RETSIGTYPE gen_sighandler(int signum) } static char thing[] = ("\n\nIt's the year 2000 is there anyone out there?\n" - "\nIf you're from another planet put your hand in the " - "air, say yeah!\n\n"); + "\nIf you're from another planet put your hand in the " + "air, say yeah!\n\n"); /*** Program entry point ***/ -int main(int argc, char *argv[]) { +int main(int argc, char *argv[]) +{ int retval; t_sr test; @@ -75,7 +81,7 @@ int main(int argc, char *argv[]) { test.sr_struct.c = 1; if (test.sr_int != 1) { fprintf(stderr, "%s: compilation variable BYTES_HIGHFIRST not set " - "correctly\n", argv[0]); + "correctly\n", argv[0]); return 1; } @@ -119,7 +125,8 @@ END_OF_MAIN(); /*** gen_reset - reset system ***/ -void gen_reset(void) { +void gen_reset(void) +{ vdp_reset(); cpu68k_reset(); cpuz80_reset(); @@ -130,134 +137,134 @@ void gen_reset(void) { /*** gen_softreset - reset system ***/ -void gen_softreset(void) { +void gen_softreset(void) +{ cpu68k_reset(); } /*** gen_loadimage - load ROM image ***/ -char *gen_loadimage(const char *filename) { +char *gen_loadimage(const char *filename) +{ int file, imagetype, bytes, bytesleft; struct stat statbuf; const char *extension; uint8 *buffer; - char countrybuf[32]; unsigned int blocks, x, i; uint8 *new; char *p; /* Remove current file */ if (cpu68k_rom) { - free(cpu68k_rom); + if (gen_freerom) + free(cpu68k_rom); cpu68k_rom = NULL; } /* Load file */ - if (stat(filename, &statbuf) != 0) { - return("Unable to stat file."); - } + if (stat(filename, &statbuf) != 0) + return ("Unable to stat file."); cpu68k_romlen = statbuf.st_size; + if (cpu68k_romlen < 0x200) + return ("File is too small"); + /* allocate enough memory plus 16 bytes for disassembler to cope with the last instruction */ - if ((cpu68k_rom = malloc(cpu68k_romlen+16)) == NULL) { + if ((cpu68k_rom = malloc(cpu68k_romlen + 16)) == NULL) { cpu68k_romlen = 0; - return("Out of memory!"); + return ("Out of memory!"); } - memset(cpu68k_rom, 0, cpu68k_romlen+16); + gen_freerom = 1; + memset(cpu68k_rom, 0, cpu68k_romlen + 16); #ifdef ALLEGRO - if ((file = open(filename, O_RDONLY|O_BINARY, 0)) == -1) { + if ((file = open(filename, O_RDONLY | O_BINARY, 0)) == -1) { #else if ((file = open(filename, O_RDONLY, 0)) == -1) { #endif perror("open"); cpu68k_rom = NULL; cpu68k_romlen = 0; - return("Unable to open file."); + return ("Unable to open file."); } buffer = cpu68k_rom; bytesleft = cpu68k_romlen; do { if ((bytes = read(file, buffer, bytesleft)) <= 0) break; - buffer+= bytes; - bytesleft-= bytes; - } while (bytesleft >= 0); + buffer += bytes; + bytesleft -= bytes; + } + while (bytesleft >= 0); close(file); if (bytes == -1) - return(strerror(errno)); + return (strerror(errno)); else if (bytes != 0) - return("invalid return code from read()"); + return ("invalid return code from read()"); if (bytesleft) { LOG_CRITICAL(("%d bytes left to read?!", bytesleft)); - return("Error whilst loading file"); + return ("Error whilst loading file"); } - imagetype = 1; /* BIN file by default */ + imagetype = 1; /* BIN file by default */ /* SMD file format check - Richard Bannister */ if ((cpu68k_rom[8] == 0xAA) && (cpu68k_rom[9] == 0xBB) && cpu68k_rom[10] == 0x06) { - imagetype = 2; /* SMD file */ + imagetype = 2; /* SMD file */ } /* check for interleaved 'SEGA' */ if (cpu68k_rom[0x280] == 'E' && cpu68k_rom[0x281] == 'A' && cpu68k_rom[0x2280] == 'S' && cpu68k_rom[0x2281] == 'G') { - imagetype = 2; /* SMD file */ + imagetype = 2; /* SMD file */ } - -#ifndef OS_ACORN /* Check extension is not wrong */ extension = filename + strlen(filename) - 3; if (extension > filename) { if (!strcasecmp(extension, "smd") && (imagetype != 2)) LOG_REQUEST(("File extension (smd) does not match detected " - "type (bin)")); + "type (bin)")); if (!strcasecmp(extension, "bin") && (imagetype != 1)) LOG_REQUEST(("File extension (bin) does not match detected " - "type (smd)")); + "type (smd)")); } -#endif /* convert to standard BIN file format */ - switch(imagetype) { - case 1: /* BIN */ + switch (imagetype) { + case 1: /* BIN */ break; - case 2: /* SMD */ - blocks = (cpu68k_romlen-512)/16384; - if (blocks*16384+512 != cpu68k_romlen) - return("Image is corrupt."); + case 2: /* SMD */ + blocks = (cpu68k_romlen - 512) / 16384; + if (blocks * 16384 + 512 != cpu68k_romlen) + return ("Image is corrupt."); - if ((new = malloc(cpu68k_romlen-512)) == NULL) { + if ((new = malloc(cpu68k_romlen - 512)) == NULL) { cpu68k_rom = NULL; cpu68k_romlen = 0; - return("Out of memory!"); + return ("Out of memory!"); } for (i = 0; i < blocks; i++) { for (x = 0; x < 8192; x++) { - new[i*16384+x*2+0] = cpu68k_rom[512+i*16384+8192+x]; - new[i*16384+x*2+1] = cpu68k_rom[512+i*16384+x]; + new[i * 16384 + x * 2 + 0] = cpu68k_rom[512 + i * 16384 + 8192 + x]; + new[i * 16384 + x * 2 + 1] = cpu68k_rom[512 + i * 16384 + x]; } } free(cpu68k_rom); cpu68k_rom = new; - cpu68k_romlen-= 512; + cpu68k_romlen -= 512; break; default: - return("Unknown image type"); + return ("Unknown image type"); break; } - /* reset system */ - gen_reset(); - /* is this icky? */ if ((p = strrchr(filename, '/')) == NULL && (p = strrchr(filename, '\\')) == NULL) { snprintf(gen_leafname, sizeof(gen_leafname), "%s", filename); } else { - snprintf(gen_leafname, sizeof(gen_leafname), "%s", p+1); + snprintf(gen_leafname, sizeof(gen_leafname), "%s", p + 1); } if ((p = strrchr(gen_leafname, '.')) != NULL) { if ((!strcasecmp(p, ".smd")) || (!strcasecmp(p, ".bin"))) @@ -266,11 +273,51 @@ char *gen_loadimage(const char *filename if (gen_leafname[0] == '\0') snprintf(gen_leafname, sizeof(gen_leafname), "rom"); + + if (gen_autodetect) { + vdp_pal = (!gen_cartinfo.flag_usa && !gen_cartinfo.flag_japan && + gen_cartinfo.flag_europe) ? 1 : 0; + } + + gen_setupcartinfo(); + + /* reset system */ + gen_reset(); + + if (gen_cartinfo.checksum != (cpu68k_rom[0x18e] << 8 | cpu68k_rom[0x18f])) + LOG_REQUEST(("Warning: Checksum does not match in ROM (%04X)", + (cpu68k_rom[0x18e] << 8 | cpu68k_rom[0x18f]))); + + LOG_REQUEST(("Loaded '%s'/'%s' (%s %04X %s)", gen_cartinfo.name_domestic, + gen_cartinfo.name_overseas, gen_cartinfo.version, + gen_cartinfo.checksum, gen_cartinfo.country)); + + return NULL; +} + +/* setup to run from ROM in memory */ + +void gen_loadmemrom(const char *rom, int romlen) +{ + cpu68k_rom = (char *)rom; /* I won't alter it, promise */ + cpu68k_romlen = romlen; + gen_freerom = 0; + gen_setupcartinfo(); + gen_reset(); +} + +/* setup gen_cartinfo from current loaded rom */ + +void gen_setupcartinfo(void) +{ + unsigned int i; + char *p; + memset(&gen_cartinfo, 0, sizeof(gen_cartinfo)); - gen_nicetext(gen_cartinfo.console, (char *)(cpu68k_rom+0x100), 16); - gen_nicetext(gen_cartinfo.copyright, (char *)(cpu68k_rom+0x110), 16); - gen_nicetext(gen_cartinfo.name_domestic, (char *)(cpu68k_rom+0x120), 48); - gen_nicetext(gen_cartinfo.name_overseas, (char *)(cpu68k_rom+0x150), 48); + gen_nicetext(gen_cartinfo.console, (char *)(cpu68k_rom + 0x100), 16); + gen_nicetext(gen_cartinfo.copyright, (char *)(cpu68k_rom + 0x110), 16); + gen_nicetext(gen_cartinfo.name_domestic, (char *)(cpu68k_rom + 0x120), 48); + gen_nicetext(gen_cartinfo.name_overseas, (char *)(cpu68k_rom + 0x150), 48); if (cpu68k_rom[0x180] == 'G' && cpu68k_rom[0x181] == 'M') { gen_cartinfo.prodtype = pt_game; } else if (cpu68k_rom[0x180] == 'A' && cpu68k_rom[0x181] == 'I') { @@ -278,10 +325,10 @@ char *gen_loadimage(const char *filename } else { gen_cartinfo.prodtype = pt_unknown; } - gen_nicetext(gen_cartinfo.version, (char *)(cpu68k_rom+0x182), 12); - gen_cartinfo.checksum = gen_checksum(((uint8 *)cpu68k_rom)+0x200, - cpu68k_romlen-0x200); - gen_nicetext(gen_cartinfo.memo, (char *)(cpu68k_rom+0x1C8), 28); + gen_nicetext(gen_cartinfo.version, (char *)(cpu68k_rom + 0x182), 12); + gen_cartinfo.checksum = gen_checksum(((uint8 *)cpu68k_rom) + 0x200, + cpu68k_romlen - 0x200); + gen_nicetext(gen_cartinfo.memo, (char *)(cpu68k_rom + 0x1C8), 28); for (i = 0x1f0; i < 0x1ff; i++) { if (cpu68k_rom[i] == 'J') gen_cartinfo.flag_japan = 1; @@ -301,21 +348,6 @@ char *gen_loadimage(const char *filename *p++ = cpu68k_rom[i]; } *p = '\0'; - - ui_setinfo(&gen_cartinfo); - - if (gen_cartinfo.checksum != (cpu68k_rom[0x18e]<<8 | cpu68k_rom[0x18f])) - LOG_REQUEST(("Warning: Checksum does not match in ROM (%04X)", - (cpu68k_rom[0x18e]<<8 | cpu68k_rom[0x18f]))); - - vdp_pal = (!gen_cartinfo.flag_usa && !gen_cartinfo.flag_japan && - gen_cartinfo.flag_europe) ? 1 : 0; - - LOG_REQUEST(("Loaded '%s'/'%s' (%s %04X %s)", gen_cartinfo.name_domestic, - gen_cartinfo.name_overseas, gen_cartinfo.version, - gen_cartinfo.checksum, gen_cartinfo.country)); - - return NULL; } /*** get_nicetext - take a string, remove spaces and capitalise ***/ @@ -323,38 +355,37 @@ char *gen_loadimage(const char *filename void gen_nicetext(char *out, char *in, unsigned int size) { int flag, i; - char c; + int c; char *start = out; - flag = 0; /* set if within word, e.g. make lowercase */ - i = size; /* maximum number of chars in input*/ - while ((c = *in++) && i--) { - if (isalpha((int)c)) { + flag = 0; /* set if within word, e.g. make lowercase */ + i = size; /* maximum number of chars in input */ + while ((c = *in++) && --i > 0) { + if (isalpha(c)) { if (!flag) { /* make uppercase */ - flag = 1; - if (islower((int)c)) { - *out++ = c - 'z'-'Z'; - } else { - *out++ = c; - } + flag = 1; + if (islower(c)) + *out++ = c - 'z' + 'Z'; + else + *out++ = c; } else { - /* make lowercase */ - if (isupper((int)c)) { - *out++ = (c) + 'z'-'Z'; - } else { - *out++ = c; - } + /* make lowercase */ + if (isupper(c)) + *out++ = (c) - 'Z' + 'z'; + else + *out++ = c; } - continue; - } - if (c == ' ' && !flag) { - continue; + } else if (c == ' ') { + if (flag) + *out++ = c; + flag = 0; + } else if (isprint(c) && c != '\t') { + flag = 0; + *out++ = c; } - *out++ = c; - flag = 0; } - if (out > start && out[-1] == ' ') + while (out > start && out[-1] == ' ') out--; *out++ = '\0'; } @@ -366,21 +397,13 @@ uint16 gen_checksum(uint8 *start, unsign uint16 checksum = 0; if (length & 1) { - length&= ~1; + length &= ~1; LOG_CRITICAL(("checksum routines given odd length (%d)", length)); } - for (; length; length-= 2, start+= 2) { - checksum+= start[0]<<8; - checksum+= start[1]; + for (; length; length -= 2, start += 2) { + checksum += start[0] << 8; + checksum += start[1]; } return checksum; } - -/*** gen_loadsavepos - load saved position ***/ - -char *gen_loadsavepos(const char *filename) -{ - LOG_REQUEST(("gen_loadsavepos: %s\n", filename)); - return("Not implemented."); -}