X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=pico%2Fcart.c;h=45f3866fdb2b38dc4e09e1bc42afa0470c8435bb;hb=c18edb34e6708b399c6bfee8dac7b21a62988643;hp=5eb89c953b6d06b40838dcc429b0c51b6ae65072;hpb=45f2f245f51ef0c0d37df3c998595c132bfcaffa;p=picodrive.git diff --git a/pico/cart.c b/pico/cart.c index 5eb89c9..45f3866 100644 --- a/pico/cart.c +++ b/pico/cart.c @@ -21,7 +21,7 @@ void (*PicoCartMemSetup)(void); void (*PicoCartLoadProgressCB)(int percent) = NULL; void (*PicoCDLoadProgressCB)(const char *fname, int percent) = NULL; // handled in Pico/cd/cd_file.c -static void PicoCartDetect(void); +static void PicoCartDetect(const char *carthw_cfg); /* cso struct */ typedef struct _cso_struct @@ -378,23 +378,21 @@ int pm_close(pm_file *fp) return ret; } - -void Byteswap(unsigned char *data,int len) +// byteswap, data needs to be int aligned, src can match dst +void Byteswap(void *dst, const void *src, int len) { - int i=0; - - if (len<2) return; // Too short + const unsigned int *ps = src; + unsigned int *pd = dst; + int i, m; - do - { - unsigned short *pd=(unsigned short *)(data+i); - int value=*pd; // Get 2 bytes + if (len < 2) + return; - value=(value<<8)|(value>>8); // Byteswap it - *pd=(unsigned short)value; // Put 2b ytes - i+=2; + m = 0x00ff00ff; + for (i = 0; i < len / 4; i++) { + unsigned int t = ps[i]; + pd[i] = ((t & m) << 8) | ((t & ~m) >> 8); } - while (i+2<=len); } // Interleve a 16k block and byteswap @@ -524,7 +522,7 @@ int PicoCartLoad(pm_file *f,unsigned char **prom,unsigned int *psize,int is_sms) elprintf(EL_STATUS, "SMD format detected."); DecodeSmd(rom,size); size-=0x200; // Decode and byteswap SMD } - else Byteswap(rom,size); // Just byteswap + else Byteswap(rom, rom, size); // Just byteswap } else { @@ -543,7 +541,7 @@ int PicoCartLoad(pm_file *f,unsigned char **prom,unsigned int *psize,int is_sms) } // Insert a cartridge: -int PicoCartInsert(unsigned char *rom,unsigned int romsize) +int PicoCartInsert(unsigned char *rom, unsigned int romsize, const char *carthw_cfg) { // notaz: add a 68k "jump one op back" opcode to the end of ROM. // This will hang the emu, but will prevent nasty crashes. @@ -574,7 +572,7 @@ int PicoCartInsert(unsigned char *rom,unsigned int romsize) carthw_chunks = NULL; if (!(PicoAHW & (PAHW_MCD|PAHW_SMS))) - PicoCartDetect(); + PicoCartDetect(carthw_cfg); // setup correct memory map for loaded ROM switch (PicoAHW) { @@ -605,6 +603,9 @@ void PicoCartUnload(void) PicoCartUnloadHook = NULL; } + if (PicoAHW & PAHW_32X) + PicoUnload32x(); + if (Pico.rom != NULL) { SekFinishIdleDet(); free(Pico.rom); @@ -612,6 +613,18 @@ void PicoCartUnload(void) } } +static unsigned int rom_crc32(void) +{ + unsigned int crc; + elprintf(EL_STATUS, "caclulating CRC32.."); + + // have to unbyteswap for calculation.. + Byteswap(Pico.rom, Pico.rom, Pico.romsize); + crc = crc32(0, Pico.rom, Pico.romsize); + Byteswap(Pico.rom, Pico.rom, Pico.romsize); + return crc; +} + static int rom_strcmp(int rom_offset, const char *s1) { int i, len = strlen(s1); @@ -643,6 +656,30 @@ static void rstrip(char *s) *p = 0; } +static int parse_3_vals(char *p, int *val0, int *val1, int *val2) +{ + char *r; + *val0 = strtoul(p, &r, 0); + if (r == p) + goto bad; + p = sskip(r); + if (*p++ != ',') + goto bad; + *val1 = strtoul(p, &r, 0); + if (r == p) + goto bad; + p = sskip(r); + if (*p++ != ',') + goto bad; + *val2 = strtoul(p, &r, 0); + if (r == p) + goto bad; + + return 1; +bad: + return 0; +} + static int is_expr(const char *expr, char **pr) { int len = strlen(expr); @@ -658,15 +695,16 @@ static int is_expr(const char *expr, char **pr) return 1; } -static void parse_carthw(int *fill_sram) +static void parse_carthw(const char *carthw_cfg, int *fill_sram) { int line = 0, any_checks_passed = 0, skip_sect = 0; + int tmp, rom_crc = 0; char buff[256], *p, *r; FILE *f; - f = fopen("carthw.cfg", "r"); + f = fopen(carthw_cfg, "r"); if (f == NULL) { - elprintf(EL_STATUS, "couldn't open carthw.txt!"); + elprintf(EL_STATUS, "couldn't open carthw.cfg!"); return; } @@ -739,6 +777,21 @@ static void parse_carthw(int *fill_sram) skip_sect = 1; continue; } + else if (is_expr("check_crc32", &p)) + { + unsigned int crc; + crc = strtoul(p, &r, 0); + if (r == p) + goto bad; + + if (rom_crc == 0) + rom_crc = rom_crc32(); + if (crc == rom_crc) + any_checks_passed = 1; + else + skip_sect = 1; + continue; + } /* now time for actions */ if (is_expr("hw", &p)) { @@ -750,12 +803,18 @@ static void parse_carthw(int *fill_sram) PicoSVPStartup(); else if (strcmp(p, "pico") == 0) PicoInitPico(); + else if (strcmp(p, "prot") == 0) + carthw_sprot_startup(); + else if (strcmp(p, "ssf2_mapper") == 0) + carthw_ssf2_startup(); else if (strcmp(p, "x_in_1_mapper") == 0) carthw_Xin1_startup(); else if (strcmp(p, "realtec_mapper") == 0) carthw_realtec_startup(); else if (strcmp(p, "radica_mapper") == 0) carthw_radica_startup(); + else if (strcmp(p, "prot_lk3") == 0) + carthw_prot_lk3_startup(); else { elprintf(EL_STATUS, "carthw:%d: unsupported mapper: %s", line, p); skip_sect = 1; @@ -823,20 +882,10 @@ static void parse_carthw(int *fill_sram) goto no_checks; rstrip(p); - scl = strtoul(p, &r, 0); - if (r == p || scl < 0 || scl > 15) - goto bad; - p = sskip(r); - if (*p++ != ',') - goto bad; - sda_in = strtoul(p, &r, 0); - if (r == p || sda_in < 0 || sda_in > 15) - goto bad; - p = sskip(r); - if (*p++ != ',') + if (!parse_3_vals(p, &scl, &sda_in, &sda_out)) goto bad; - sda_out = strtoul(p, &r, 0); - if (r == p || sda_out < 0 || sda_out > 15) + if (scl < 0 || scl > 15 || sda_in < 0 || sda_in > 15 || + sda_out < 0 || sda_out > 15) goto bad; SRam.eeprom_bit_cl = scl; @@ -844,6 +893,18 @@ static void parse_carthw(int *fill_sram) SRam.eeprom_bit_out= sda_out; continue; } + else if ((tmp = is_expr("prot_ro_value16", &p)) || is_expr("prot_rw_value16", &p)) { + int addr, mask, val; + if (!any_checks_passed) + goto no_checks; + rstrip(p); + + if (!parse_3_vals(p, &addr, &mask, &val)) + goto bad; + + carthw_sprot_new_location(addr, mask, val, tmp ? 1 : 0); + continue; + } bad: @@ -863,11 +924,9 @@ no_checks: /* * various cart-specific things, which can't be handled by generic code */ -static void PicoCartDetect(void) +static void PicoCartDetect(const char *carthw_cfg) { - int fill_sram = 0, csum; - - csum = rom_read32(0x18c) & 0xffff; + int fill_sram = 0; memset(&SRam, 0, sizeof(SRam)); if (Pico.rom[0x1B1] == 'R' && Pico.rom[0x1B0] == 'A') @@ -895,7 +954,8 @@ static void PicoCartDetect(void) SRam.eeprom_bit_in = 0; SRam.eeprom_bit_out= 0; - parse_carthw(&fill_sram); + if (carthw_cfg != NULL) + parse_carthw(carthw_cfg, &fill_sram); if (SRam.flags & SRF_ENABLED) {