@@ -76,6 +76,11 @@ void timeout_event(void* user, unsigned id, unsigned late)
7676
7777static uint16_t find_rom_header_offset (const uint8_t * data )
7878{
79+ if (!data )
80+ {
81+ return 0 ;
82+ }
83+
7984 // loop until we find the magic num
8085 // the rom header can start at 1 of 3 offsets
8186 const uint16_t offsets [] =
@@ -255,6 +260,25 @@ static void log_header(const struct SMS_RomHeader* header)
255260 SMS_log ("rom_size: [0x%X] [%s]\n" , header -> rom_size , valid_rom_size_string [header -> rom_size ]);
256261}
257262
263+ static void setup_cart (struct SMS_CartRom * cart , const uint8_t * rom , size_t size )
264+ {
265+ // save the rom, setup the size and mask
266+ if (!rom || size < 0x400 )
267+ {
268+ cart -> rom = NULL ;
269+ cart -> rom_size = 0 ;
270+ cart -> rom_mask = 1 ; // avoid division by zero.
271+ cart -> max_bank_mask = 1 ;
272+ }
273+ else
274+ {
275+ cart -> rom = rom ;
276+ cart -> rom_size = size ;
277+ cart -> rom_mask = size / 0x400 ; // this works because size is always pow2
278+ cart -> max_bank_mask = size / 0x4000 ;
279+ }
280+ }
281+
258282bool SMS_init (struct SMS_Core * sms )
259283{
260284 if (!sms )
@@ -290,6 +314,9 @@ bool SMS_init(struct SMS_Core* sms)
290314 return false;
291315 }
292316
317+ setup_cart (& sms -> cart , NULL , 0 );
318+ setup_cart (& sms -> cart_bios , NULL , 0 );
319+
293320 return true;
294321}
295322
@@ -303,7 +330,7 @@ void SMS_quit(struct SMS_Core* sms)
303330 }
304331}
305332
306- static void SMS_reset (struct SMS_Core * sms )
333+ void SMS_reset (struct SMS_Core * sms )
307334{
308335 // do NOT reset cart!
309336 memset (sms -> rmap , 0 , sizeof (sms -> rmap ));
@@ -358,12 +385,12 @@ static void SMS_reset(struct SMS_Core* sms)
358385bool SMS_has_bios (const struct SMS_Core * sms )
359386{
360387 // bios should be at least 1-page size in size
361- return sms -> bios && sms -> bios_size >= 1024 && sms -> bios_size <= SMS_ROM_SIZE_MAX ;
388+ return sms -> cart_bios . rom && sms -> cart_bios . rom_size >= 1024 && sms -> cart_bios . rom_size <= SMS_ROM_SIZE_MAX ;
362389}
363390
364391bool SMS_has_rom (const struct SMS_Core * sms )
365392{
366- return sms -> rom != NULL ;
393+ return sms -> cart . rom != NULL ;
367394}
368395
369396size_t SMS_cycles_per_frame (const struct SMS_Core * sms )
@@ -388,23 +415,19 @@ double SMS_target_fps_region(enum SMS_Region region)
388415
389416bool SMS_loadbios (struct SMS_Core * sms , const uint8_t * bios , size_t size )
390417{
391- sms -> bios = bios ;
392- sms -> bios_size = size ;
393-
394418 // todo: hash all known bios to know exactly what bios is being loaded
395- if (!SMS_has_bios (sms ))
419+ setup_cart (& sms -> cart_bios , bios , size );
420+
421+ if (find_rom_header_offset (bios ))
396422 {
397- return false;
423+ SMS_log ("bios is sega mapper\n" );
424+ sms -> cart_bios .mapper_type = MAPPER_TYPE_SEGA ;
398425 }
399-
400- // todo: impl below
401- // if bios is greater than a page, then it likely has rom builtin
402- #if 0
403- if (sms -> bios_size > 1024 * 32 )
426+ else
404427 {
405- SMS_loadrom (sms , bios + 1024 * 0 , sms -> bios_size - 1024 * 0 , -1 );
428+ SMS_log ("bios set to no mapper\n" );
429+ sms -> cart_bios .mapper_type = MAPPER_TYPE_NONE ;
406430 }
407- #endif
408431
409432 return true;
410433}
@@ -416,10 +439,7 @@ static bool sg_loadrom(struct SMS_Core* sms, const uint8_t* rom, size_t size, in
416439 SMS_log ("[INFO] trying to load sg rom\n" );
417440
418441 // save the rom, setup the size and mask
419- sms -> rom = rom ;
420- sms -> rom_size = size ;
421- sms -> rom_mask = size / 0x400 ; // this works because size is always pow2
422- sms -> cart .max_bank_mask = size / 0x4000 ;
442+ setup_cart (& sms -> cart , rom , size );
423443 sms -> crc = SMS_crc32 (rom , size );
424444
425445 SMS_log ("crc32 0x%08X\n" , sms -> crc );
@@ -436,10 +456,7 @@ static bool sg_loadrom(struct SMS_Core* sms, const uint8_t* rom, size_t size, in
436456static bool loadrom2 (struct SMS_Core * sms , struct RomEntry * entry , const uint8_t * rom , size_t size )
437457{
438458 // save the rom, setup the size and mask
439- sms -> rom = rom ;
440- sms -> rom_size = size ;
441- sms -> rom_mask = size / 0x400 ; // this works because size is always pow2
442- sms -> cart .max_bank_mask = size / 0x4000 ;
459+ setup_cart (& sms -> cart , rom , size );
443460 sms -> crc = entry -> crc ;
444461
445462 SMS_set_system_type (sms , entry -> sys );
@@ -459,9 +476,6 @@ bool SMS_loadrom(struct SMS_Core* sms, const uint8_t* rom, size_t size)
459476bool SMS_loadromEx (struct SMS_Core * sms , const uint8_t * rom , size_t size , int system , int region , int console )
460477{
461478 assert (sms );
462- assert (rom );
463- assert (size );
464- assert (sms && rom && size );
465479
466480 SMS_log ("[INFO] loadrom called with rom size: 0x%zX\n" , size );
467481
@@ -481,6 +495,13 @@ bool SMS_loadromEx(struct SMS_Core* sms, const uint8_t* rom, size_t size, int sy
481495
482496 sms -> console = console ;
483497
498+ // handle unmapping of the rom.
499+ if (!rom || !size )
500+ {
501+ setup_cart (& sms -> cart , NULL , 0 );
502+ return true;
503+ }
504+
484505 struct RomEntry entry = {0 };
485506 const uint32_t crc = SMS_crc32 (rom , size );
486507 SMS_log ("crc32 0x%08X\n" , crc );
@@ -527,10 +548,7 @@ bool SMS_loadromEx(struct SMS_Core* sms, const uint8_t* rom, size_t size, int sy
527548 }
528549
529550 // save the rom, setup the size and mask
530- sms -> rom = rom ;
531- sms -> rom_size = size ;
532- sms -> rom_mask = size / 0x400 ; // this works because size is always pow2
533- sms -> cart .max_bank_mask = size / 0x4000 ;
551+ setup_cart (& sms -> cart , rom , size );
534552 sms -> crc = crc ;
535553
536554 SMS_log ("crc32 0x%08X\n" , sms -> crc );
@@ -560,28 +578,28 @@ bool SMS_loadromEx(struct SMS_Core* sms, const uint8_t* rom, size_t size, int sy
560578
561579bool SMS_loadsave (struct SMS_Core * sms , const uint8_t * data , size_t size )
562580{
563- if (!data || !size || size != sizeof (sms -> cart .ram ))
581+ if (!data || !size || size != sizeof (sms -> cart_ram .ram ))
564582 {
565583 return false;
566584 }
567585
568- memcpy (sms -> cart .ram , data , size );
586+ memcpy (sms -> cart_ram .ram , data , size );
569587 return true;
570588}
571589
572590bool SMS_used_sram (const struct SMS_Core * sms )
573591{
574- return sms -> cart . sram_used ;
592+ return sms -> cart_ram . used ;
575593}
576594
577595bool SMS_is_sram_dirty (struct SMS_Core * sms , bool clear )
578596{
579- const bool flag = sms -> cart . sram_dirty ;
597+ const bool flag = sms -> cart_ram . dirty ;
580598
581599 if (clear )
582600 {
583601 // check if sram is mounted, if so, re-enable dirty flag.
584- sms -> cart . sram_dirty = mapper_is_sram_mapped (sms );
602+ sms -> cart_ram . dirty = mapper_is_sram_mapped (sms );
585603 }
586604
587605 return flag ;
0 commit comments