Previous 199869 Revisions Next

r21699 Friday 8th March, 2013 at 10:01:28 UTC by Fabio Priuli
greatly simplified mapping and access for cart ROM. given the massive internal changes, please test once again
your favorite SNES games against previous code (or against latest release) and report regressions. thanks.
[src/mame/drivers]snesb.c
[src/mame/includes]snes.h
[src/mame/machine]snes.c
[src/mess/drivers]snes.c
[src/mess/machine]snescart.c

trunk/src/mame/drivers/snesb.c
r21698r21699
215215
216216READ8_MEMBER(snesb_state::sb2b_7xxx_r)
217217{
218   return snes_ram[0xc07000 + offset];
218   return space.read_byte(0xc07000 + offset);
219219}
220220
221221
r21698r21699
806806
807807   for (i =0; i < 0x80000 * 3; i++)
808808   {
809         cipherText = src[i];
810         plainText = data_substitution0[cipherText & 0xf] | data_substitution1[cipherText >> 4];
809      cipherText = src[i];
810      plainText = data_substitution0[cipherText & 0xf] | data_substitution1[cipherText >> 4];
811811      newAddress = (address_substitution_high[i >> 15] << 15) | (i & 0x7fc0) | (address_substitution_low[i & 0x3f]);
812812
813813      if (newAddress < 0x10000)
trunk/src/mame/machine/snes.c
r21698r21699
676676
677677*/
678678
679static UINT8 snes_rom_access(running_machine &machine, UINT32 offset)
680{
681   snes_state *state = machine.driver_data<snes_state>();
682   UINT32 addr;
683   UINT8 value = 0xff;
684   UINT8 base_bank = (offset < 0x800000) ? 0x80 : 0x00;
685
686   switch (state->m_cart[0].mode)
687   {
688      case SNES_MODE_20:
689      case SNES_MODE_22:
690         addr = (state->m_cart[0].rom_bank_map[offset/0x10000] * 0x8000) + (offset & 0x7fff);
691         value = state->m_cart[0].m_rom[addr];
692         break;
693      case SNES_MODE_21:
694      case SNES_MODE_25:
695         offset &= 0x3fffff;
696         addr = (state->m_cart[0].rom_bank_map[base_bank + (offset/0x8000)] * 0x8000) + (offset & 0x7fff);
697         value = state->m_cart[0].m_rom[addr];
698         break;
699   }
700
701   return value;
702}
703
679704/* 0x000000 - 0x7dffff */
680705READ8_HANDLER( snes_r_bank1 )
681706{
r21698r21699
702727            value = snes_open_bus_r(space, 0);                              /* Reserved */
703728      }
704729      else
705         value = snes_ram[offset];   //ROM
730         value = snes_rom_access(space.machine(), offset);   //ROM
706731   }
707732   else if (offset < 0x700000)
708733   {
709734      if (state->m_cart[0].mode & 5 && address < 0x8000)  /* Mode 20 & 22 in 0x0000-0x7fff */
710735         value = snes_open_bus_r(space, 0);
711736      else
712         value = snes_ram[offset];    //ROM
737         value = snes_rom_access(space.machine(), offset);    //ROM
713738   }
714739   else
715740   {
r21698r21699
734759         }
735760      }
736761      else
737         value = snes_ram[offset];    //ROM
762         value = snes_rom_access(space.machine(), offset);    //ROM
738763   }
739   
764
740765   return value;
741766}
742767
r21698r21699
753778      if (address < 0x8000)
754779         value = space.read_byte(offset);
755780      else
756         value = snes_ram[0x800000 + offset];    //ROM
781         value = snes_rom_access(space.machine(), 0x800000 + offset);    //ROM
757782   }
758783   else
759784   {
r21698r21699
783808         }
784809      }
785810      else
786         value = snes_ram[0x800000 + offset];    //ROM
811         value = snes_rom_access(space.machine(), 0x800000 + offset);    //ROM
787812   }
788     
813
789814   return value;
790815}
791816
r21698r21699
813838         }
814839         else
815840            logerror("(PC=%06x) snes_w_bank1: Attempt to write to reserved address: %X = %02X\n", space.device().safe_pc(), offset, data);
816      }         
841      }
817842      else
818843         logerror("(PC=%06x) Attempt to write to ROM address: %X\n", space.device().safe_pc(), offset);
819844   }
r21698r21699
853878{
854879   snes_state *state = space.machine().driver_data<snes_state>();
855880   UINT16 address = offset & 0xffff;
856   
881
857882   if (offset < 0x400000)
858883   {
859884      if (address < 0x8000)
r21698r21699
11581183}
11591184
11601185
1186void snes_state::rom_map_setup(UINT32 size)
1187{
1188   int i;
1189   // setup the rom_bank_map array to faster ROM read
1190   for (i = 0; i < size / 0x8000; i++)
1191      m_cart[0].rom_bank_map[i] = i;
1192
1193   // fill up remaining blocks with mirrors
1194   while (i % 256)
1195   {
1196      int j = 0, repeat_banks;
1197      while ((i % (256 >> j)) && j < 8)
1198         j++;
1199      repeat_banks = i % (256 >> (j - 1));
1200      for (int k = 0; k < repeat_banks; k++)
1201         m_cart[0].rom_bank_map[i + k] = m_cart[0].rom_bank_map[i + k - repeat_banks];
1202      i += repeat_banks;
1203   }
1204}
1205
11611206/* for mame we use an init, maybe we will need more for the different games */
11621207DRIVER_INIT_MEMBER(snes_state,snes)
11631208{
1164   UINT16 total_blocks, read_blocks;
1165   UINT8 *rom;
1166
1167   rom = memregion("user3")->base();
1209   UINT8 *rom = memregion("user3")->base();
11681210   snes_ram = auto_alloc_array_clear(machine(), UINT8, 0x1400000);
11691211
11701212   m_cart[0].m_rom_size = memregion("user3")->bytes();
11711213   m_cart[0].m_rom = auto_alloc_array_clear(machine(), UINT8, m_cart[0].m_rom_size);
11721214   memcpy(m_cart[0].m_rom, rom, m_cart[0].m_rom_size);
1215   rom_map_setup(m_cart[0].m_rom_size);
11731216
11741217   m_cart[0].m_nvram_size = 0;
11751218   if (rom[0x7fd8] > 0)
r21698r21699
11851228   /* all NSS games seem to use MODE 20 */
11861229   m_cart[0].mode = SNES_MODE_20;
11871230   m_has_addon_chip = HAS_NONE;
1188
1189   /* Find the number of blocks in this ROM */
1190   total_blocks = (memregion("user3")->bytes() / 0x8000);
1191   read_blocks = 0;
1192
1193   /* Loading all the data blocks from cart, we only partially cover banks 0x00 to 0x7f. Therefore, we
1194    * have to mirror the blocks until we reach the end. E.g. for a 11Mbits image (44 blocks), we proceed
1195    * as follows:
1196    * 11 Mbits = 8 Mbits (blocks 1->32) + 2 Mbits (blocks 33->40) + 1 Mbit (blocks 41->44).
1197    * Hence, we fill memory up to 16 Mbits (banks 0x00 to 0x3f) mirroring the final part:
1198    * 8 Mbits (blocks 1->32) + 2 Mbits (blocks 33->40) + 1 Mbit (blocks 41->44) + 1 Mbit (blocks 41->44)
1199    *   + 2 Mbits (blocks 33->40) + 1 Mbit (blocks 41->44) + 1 Mbit (blocks 41->44).
1200    * And we repeat the same blocks in the second half of the banks (banks 0x40 to 0x7f).
1201    * This is likely what happens in the real SNES as well, because the unit cannot be aware of the exact
1202    * size of data in the cart (procedure confirmed by byuu)
1203    */
1204
1205   /* LoROM carts load data in banks 0x00 to 0x7f at address 0x8000 (actually up to 0x7d, because 0x7e and
1206    * 0x7f are overwritten by WRAM). Each block is also mirrored in banks 0x80 to 0xff (up to 0xff for real)
1207    */
1208   while (read_blocks < 128 && read_blocks < total_blocks)
1209   {
1210      /* Loading data */
1211      memcpy(&snes_ram[0x008000 + read_blocks * 0x10000], &rom[read_blocks * 0x08000], 0x8000);
1212      /* Mirroring */
1213      memcpy(&snes_ram[0x808000 + read_blocks * 0x10000], &snes_ram[0x8000 + read_blocks * 0x10000], 0x8000);
1214      read_blocks++;
1215   }
1216   /* Filling banks up to 0x7f and their mirrors */
1217   while (read_blocks % 128)
1218   {
1219      int j = 0, repeat_blocks;
1220      while ((read_blocks % (128 >> j)) && j < 7)
1221         j++;
1222      repeat_blocks = read_blocks % (128 >> (j - 1));
1223
1224      memcpy(&snes_ram[read_blocks * 0x10000], &snes_ram[(read_blocks - repeat_blocks) * 0x10000], repeat_blocks * 0x10000);
1225      memcpy(&snes_ram[0x800000 + read_blocks * 0x10000], &snes_ram[0x800000 + (read_blocks - repeat_blocks) * 0x10000], repeat_blocks * 0x10000);
1226
1227      read_blocks += repeat_blocks;
1228   }
12291231}
12301232
12311233DRIVER_INIT_MEMBER(snes_state,snes_hirom)
12321234{
1233   UINT16 total_blocks, read_blocks;
1234   UINT8  *rom;
1235
1236   rom = memregion("user3")->base();
1235   UINT8  *rom = memregion("user3")->base();
12371236   snes_ram = auto_alloc_array(machine(), UINT8, 0x1400000);
12381237   memset(snes_ram, 0, 0x1400000);
12391238
12401239   m_cart[0].m_rom_size = memregion("user3")->bytes();
12411240   m_cart[0].m_rom = auto_alloc_array_clear(machine(), UINT8, m_cart[0].m_rom_size);
12421241   memcpy(m_cart[0].m_rom, rom, m_cart[0].m_rom_size);
1242   rom_map_setup(m_cart[0].m_rom_size);
12431243
12441244   m_cart[0].m_nvram_size = 0;
12451245   if (rom[0xffd8] > 0)
r21698r21699
12541254
12551255   m_cart[0].mode = SNES_MODE_21;
12561256   m_has_addon_chip = HAS_NONE;
1257
1258   /* Find the number of blocks in this ROM */
1259   total_blocks = (memregion("user3")->bytes() / 0x10000);
1260   read_blocks = 0;
1261
1262   /* See above for details about the way we fill banks 0x00 to 0x7f */
1263
1264   /* HiROM carts load data in banks 0xc0 to 0xff. Each bank is fully mirrored in banks 0x40 to 0x7f
1265    * (actually up to 0x7d, because 0x7e and 0x7f are overwritten by WRAM). The top half (address
1266    * range 0x8000 - 0xffff) of each bank is also mirrored in banks 0x00 to 0x3f and 0x80 to 0xbf.
1267    */
1268   while (read_blocks < 64 && read_blocks < total_blocks)
1269   {
1270      /* Loading data */
1271      memcpy(&snes_ram[0xc00000 + read_blocks * 0x10000], &rom[read_blocks * 0x10000], 0x10000);
1272      /* Mirroring */
1273      memcpy(&snes_ram[0x008000 + read_blocks * 0x10000], &snes_ram[0xc08000 + read_blocks * 0x10000], 0x8000);
1274      memcpy(&snes_ram[0x400000 + read_blocks * 0x10000], &snes_ram[0xc00000 + read_blocks * 0x10000], 0x10000);
1275      memcpy(&snes_ram[0x808000 + read_blocks * 0x10000], &snes_ram[0xc08000 + read_blocks * 0x10000], 0x8000);
1276      read_blocks++;
1277   }
1278   /* Filling banks up to 0x7f and their mirrors */
1279   while (read_blocks % 64)
1280   {
1281      int j = 0, repeat_blocks;
1282      while ((read_blocks % (64 >> j)) && j < 6)
1283         j++;
1284      repeat_blocks = read_blocks % (64 >> (j - 1));
1285
1286      memcpy(&snes_ram[0xc00000 + read_blocks * 0x10000], &snes_ram[0xc00000 + (read_blocks - repeat_blocks) * 0x10000], repeat_blocks * 0x10000);
1287      memcpy(&snes_ram[read_blocks * 0x10000], &snes_ram[(read_blocks - repeat_blocks) * 0x10000], repeat_blocks * 0x10000);
1288      memcpy(&snes_ram[0x400000 + read_blocks * 0x10000], &snes_ram[0x400000 + (read_blocks - repeat_blocks) * 0x10000], repeat_blocks * 0x10000);
1289      memcpy(&snes_ram[0x800000 + read_blocks * 0x10000], &snes_ram[0x800000 + (read_blocks - repeat_blocks) * 0x10000], repeat_blocks * 0x10000);
1290      read_blocks += repeat_blocks;
1291   }
12921257}
12931258
12941259
trunk/src/mame/includes/snes.h
r21698r21699
558558   UINT8  mode;        /* ROM memory mode */
559559   UINT32 sram_max;    /* Maximum amount sram in cart (based on ROM mode) */
560560   int    slot_in_use; /* this is needed by Sufami Turbo slots (to check if SRAM has to be saved) */
561   UINT8 rom_bank_map[0x100];
561562};
562563
563564struct snes_joypad
r21698r21699
650651   UINT8 m_has_addon_chip;
651652   UINT32 m_cart_size;
652653   snes_cart_info m_cart[2];   // the second one is used by MESS for Sufami Turbo and, eventually, BS-X
654   void rom_map_setup(UINT32 size);
653655
654656   snes_ppu_class        m_ppu;
655657   UINT32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
trunk/src/mess/drivers/snes.c
r21698r21699
6161   DECLARE_READ8_MEMBER( superfx_r_bank2 );
6262   DECLARE_READ8_MEMBER( superfx_r_bank3 );
6363   DECLARE_WRITE8_MEMBER( superfx_w_bank3 );
64   DECLARE_READ8_MEMBER( sufami_r );
65   DECLARE_WRITE8_MEMBER( sufami_w );
6466   CUSTOM_INPUT_MEMBER( snes_mouse_speed_input );
6567   CUSTOM_INPUT_MEMBER( snes_superscope_offscreen_input );
6668   TIMER_CALLBACK_MEMBER( lightgun_tick );
r21698r21699
138140   m_upd96050->dataram_w(addr/2, temp);
139141}
140142
141
142143READ8_MEMBER( snes_console_state::sfx_r )
143144{
144145   UINT16 address = offset & 0xffff;
r21698r21699
156157      else if (address < 0x8000)
157158         return superfx_access_ram(m_superfx) ? m_sfx_ram[offset & 0x1fff] : snes_open_bus_r(space, 0);
158159      else
159         return snes_ram[offset];
160         return m_cart[0].m_rom[m_cart[0].rom_bank_map[offset / 0x10000] * 0x8000 + (offset & 0x7fff)];
160161   }
161162   else if (offset < 0x600000)
162163   {
163164      if (superfx_access_rom(m_superfx))
164         return snes_ram[offset];
165         return m_cart[0].m_rom[m_cart[0].rom_bank_map[(offset - 0x400000) / 0x8000] * 0x8000 + (offset & 0x7fff)];
165166      else
166167      {
167168         static const UINT8 sfx_data[16] = {
r21698r21699
468469   snes_w_bank2(space, offset, data, 0xff);
469470}
470471
472READ8_MEMBER( snes_console_state::sufami_r )
473{
474   UINT16 address = offset & 0xffff;
475   if (offset < 0x200000)
476   {
477      if (address < 0x2000)
478         return space.read_byte(0x7e0000 + address);
479      else if (address < 0x6000)
480         return snes_r_io(space, address);
481      else if (address < 0x8000)
482         return snes_open_bus_r(space, 0);
483      else
484      {
485         UINT8 *ROM = memregion("sufami")->base();
486         int bank = (offset / 0x10000) & 7;
487         return ROM[bank * 0x8000 + (offset & 0x7fff)]; // SUFAMI ROM
488      }
489   }
490   else if (offset < 0x400000)
491   {
492      if (address < 0x2000)
493         return space.read_byte(0x7e0000 + address);
494      else if (address < 0x6000)
495         return snes_r_io(space, address);
496      else if (address < 0x8000)
497         return snes_open_bus_r(space, 0);
498      else if (m_cart[0].slot_in_use)
499      {
500         int bank = (offset - 0x200000) / 0x10000;
501         return m_cart[0].m_rom[m_cart[0].rom_bank_map[bank] * 0x8000 + (offset & 0x7fff)]; // SUFAMI SLOT1
502      }
503   }
504   else if (offset < 0x600000)
505   {
506      if (address < 0x8000)
507         return snes_open_bus_r(space, 0);
508      else if (m_cart[1].slot_in_use)
509      {
510         int bank = (offset - 0x400000) / 0x10000;
511         return m_cart[1].m_rom[m_cart[1].rom_bank_map[bank] * 0x8000 + (offset & 0x7fff)]; // SUFAMI SLOT2
512      }
513   }
514   else if (address >= 0x8000 && ((offset >= 0x600000 && offset < 0x640000) || (offset >= 0x700000 && offset < 0x740000)))
515   {
516      int slot_id = (offset & 0x100000) ? 1 : 0;
517      if (m_cart[slot_id].slot_in_use)
518      {
519         int bank = (offset & 0x3ffff) / 0x10000;
520         return m_cart[slot_id].m_nvram[bank * 0x8000 + (offset & 0x7fff)];  // SLOT RAM
521      }
522   }
523   return snes_open_bus_r(space, 0);
524}
525
526WRITE8_MEMBER( snes_console_state::sufami_w )
527{
528   UINT16 address = offset & 0xffff;
529   if (offset < 0x400000)
530   {
531      if (address < 0x2000)
532         space.write_byte(0x7e0000 + address, data);
533      else if (address < 0x6000)
534         snes_w_io(space, address, data);
535   }
536   else if (address >= 0x8000 && ((offset >= 0x600000 && offset < 0x640000) || (offset >= 0x700000 && offset < 0x740000)))
537   {
538      int slot_id = (offset & 0x100000) ? 1 : 0;
539      if (m_cart[slot_id].slot_in_use)
540      {
541         int bank = (offset & 0x3ffff) / 0x10000;
542         m_cart[slot_id].m_nvram[bank * 0x8000 + (offset & 0x7fff)] = data;  // SLOT RAM
543      }
544   }
545}
546
471547READ8_MEMBER( snes_console_state::superfx_r_bank1 )
472548{
473   return snes_ram[offset | 0x8000];
549   return m_cart[0].m_rom[m_cart[0].rom_bank_map[offset / 0x10000] * 0x8000 + (offset & 0x7fff)];
474550}
475551
476552READ8_MEMBER( snes_console_state::superfx_r_bank2 )
477553{
478   return snes_ram[0x400000 + offset];
554   return m_cart[0].m_rom[m_cart[0].rom_bank_map[offset / 0x8000] * 0x8000 + (offset & 0x7fff)];
479555}
480556
481557READ8_MEMBER( snes_console_state::superfx_r_bank3 )
482558{
483559   /* IMPORTANT: SFX RAM sits in 0x600000-0x7fffff, and it's mirrored in 0xe00000-0xffffff. However, SNES
484560    has only access to 0x600000-0x7dffff (because there is WRAM after that). */
485   //printf("superfx_r_bank3: %08x = %02x\n", offset, snes_ram[0xe00000 + offset]);
561   //printf("superfx_r_bank3: %08x = %02x\n", offset, m_sfx_ram[offset & 0xfffff]);
486562   return m_sfx_ram[offset & 0xfffff];
487563}
488564
r21698r21699
506582   AM_RANGE(0x800000, 0xffffff) AM_READWRITE(snes_hi_r, snes_hi_w)
507583ADDRESS_MAP_END
508584
585static ADDRESS_MAP_START( snesst_map, AS_PROGRAM, 8, snes_console_state )
586   AM_RANGE(0x000000, 0x7dffff) AM_READWRITE(sufami_r, sufami_w)
587   AM_RANGE(0x7e0000, 0x7fffff) AM_RAM                 /* 8KB Low RAM, 24KB High RAM, 96KB Expanded RAM */
588   AM_RANGE(0x800000, 0xffffff) AM_READWRITE(sufami_r, sufami_w)
589ADDRESS_MAP_END
590
509591static ADDRESS_MAP_START( superfx_map, AS_PROGRAM, 8, snes_console_state )
510592   AM_RANGE(0x000000, 0x3fffff) AM_READ(superfx_r_bank1)
511593   AM_RANGE(0x400000, 0x5fffff) AM_READ(superfx_r_bank2)
r21698r21699
12951377MACHINE_CONFIG_END
12961378
12971379static MACHINE_CONFIG_DERIVED( snesst, snes_base )
1380   MCFG_CPU_MODIFY( "maincpu" )
1381   MCFG_CPU_PROGRAM_MAP(snesst_map)
12981382
12991383   MCFG_MACHINE_START(snesst)
13001384
r21698r21699
15841668
15851669   if (m_type == SNES_SUFAMITURBO && address >= 0x8000 && ((offset >= 0x600000 && offset < 0x640000) || (offset >= 0x700000 && offset < 0x740000)))
15861670   { m_slotcart->m_cart->write_h(space, offset, data); return; }
1587   
1671
15881672   if (offset < 0x400000)
15891673   {
15901674      if (address < 0x2000)
r21698r21699
16311715   {
16321716      if (m_type == SNES_SUFAMITURBO && address >= 0x8000 && offset < 0x740000)
16331717         return m_slotcart->m_cart->read_l(space, offset);
1634     
1718
16351719      // here usually there is SRAM mirrored in the whole range, but if ROM is very large then arrives here too (see tokimeki and wizardg4)
16361720      if (m_slotcart->m_cart->get_rom_size() > 0x200000 && address >= 0x8000)
16371721         return m_slotcart->m_cart->read_l(space, offset);
r21698r21699
17411825            int mask = (m_slotcart->m_cart->get_nvram_size() - 1) & 0x7fff;
17421826            return m_slotcart->m_cart->read_ram(space, (offset - 0x6000) & mask);
17431827         }
1744         
1828
17451829         if (m_slotcart->m_cart->get_nvram_size() && offset >= 0x300000)
17461830         {
17471831            /* Donkey Kong Country checks this and detects a copier if 0x800 is not masked out due to sram size */
r21698r21699
18051889      }
18061890      else if (address < 0x8000)
18071891         return m_slotcart->m_cart->read_ram(space, offset & 0x1fff);
1808      else
1892      else
18091893         return m_slotcart->m_cart->read_h(space, offset);
18101894   }
18111895   else if (offset < 0x600000)
r21698r21699
19862070   }
19872071   else if (offset >= 0x700000 && address < 0x8000 && m_slotcart->m_cart->get_nvram_size())    // NVRAM access
19882072      return m_slotcart->m_cart->read_ram(space, offset);
1989   else   // ROM access
2073   else    // ROM access
19902074      return m_slotcart->m_cart->read_l(space, offset);
19912075}
19922076
r21698r21699
20962180READ8_MEMBER( snsnew_state::snesbsx_lo_r )
20972181{
20982182   UINT16 address = offset & 0xffff;
2099   
2183
21002184   if (offset < 0x400000)
21012185   {
21022186      if (address < 0x2000)
r21698r21699
24582542   switch (state->m_type)
24592543   {
24602544      case SNES_MODE21:
2461//         machine.device("maincpu")->memory().space(AS_PROGRAM).install_readwrite_handler(0x000000, 0x7dffff, read8_delegate(FUNC(snsnew_state::snes21_lo_r),state), write8_delegate(FUNC(snsnew_state::snes21_lo_w),state));
2462//         machine.device("maincpu")->memory().space(AS_PROGRAM).install_readwrite_handler(0x800000, 0xffffff, read8_delegate(FUNC(snsnew_state::snes21_hi_r),state), write8_delegate(FUNC(snsnew_state::snes21_hi_w),state));
2463//         set_5a22_map(*state->m_maincpu);
2545//          machine.device("maincpu")->memory().space(AS_PROGRAM).install_readwrite_handler(0x000000, 0x7dffff, read8_delegate(FUNC(snsnew_state::snes21_lo_r),state), write8_delegate(FUNC(snsnew_state::snes21_lo_w),state));
2546//          machine.device("maincpu")->memory().space(AS_PROGRAM).install_readwrite_handler(0x800000, 0xffffff, read8_delegate(FUNC(snsnew_state::snes21_hi_r),state), write8_delegate(FUNC(snsnew_state::snes21_hi_w),state));
2547//          set_5a22_map(*state->m_maincpu);
24642548         break;
24652549      case SNES_DSP_MODE21:
2466//         machine.device("maincpu")->memory().space(AS_PROGRAM).install_readwrite_handler(0x000000, 0x7dffff, read8_delegate(FUNC(snsnew_state::snes21_lo_r),state), write8_delegate(FUNC(snsnew_state::snes21_lo_w),state));
2467//         machine.device("maincpu")->memory().space(AS_PROGRAM).install_readwrite_handler(0x800000, 0xffffff, read8_delegate(FUNC(snsnew_state::snes21_hi_r),state), write8_delegate(FUNC(snsnew_state::snes21_hi_w),state));
2468//         machine.device("maincpu")->memory().space(AS_PROGRAM).install_read_handler(0x006000, 0x007fff, 0, 0x9f0000, read8_delegate(FUNC(device_sns_cart_interface::chip_read),state->m_slotcart->m_cart));
2469//         machine.device("maincpu")->memory().space(AS_PROGRAM).install_write_handler(0x006000, 0x007fff, 0, 0x9f0000, write8_delegate(FUNC(device_sns_cart_interface::chip_write),state->m_slotcart->m_cart));
2470//         set_5a22_map(*state->m_maincpu);
2550//          machine.device("maincpu")->memory().space(AS_PROGRAM).install_readwrite_handler(0x000000, 0x7dffff, read8_delegate(FUNC(snsnew_state::snes21_lo_r),state), write8_delegate(FUNC(snsnew_state::snes21_lo_w),state));
2551//          machine.device("maincpu")->memory().space(AS_PROGRAM).install_readwrite_handler(0x800000, 0xffffff, read8_delegate(FUNC(snsnew_state::snes21_hi_r),state), write8_delegate(FUNC(snsnew_state::snes21_hi_w),state));
2552//          machine.device("maincpu")->memory().space(AS_PROGRAM).install_read_handler(0x006000, 0x007fff, 0, 0x9f0000, read8_delegate(FUNC(device_sns_cart_interface::chip_read),state->m_slotcart->m_cart));
2553//          machine.device("maincpu")->memory().space(AS_PROGRAM).install_write_handler(0x006000, 0x007fff, 0, 0x9f0000, write8_delegate(FUNC(device_sns_cart_interface::chip_write),state->m_slotcart->m_cart));
2554//          set_5a22_map(*state->m_maincpu);
24712555         break;
24722556      case SNES_SRTC:
2473//         machine.device("maincpu")->memory().space(AS_PROGRAM).install_readwrite_handler(0x000000, 0x7dffff, read8_delegate(FUNC(snsnew_state::snes21_lo_r),state), write8_delegate(FUNC(snsnew_state::snes21_lo_w),state));
2474//         machine.device("maincpu")->memory().space(AS_PROGRAM).install_readwrite_handler(0x800000, 0xffffff, read8_delegate(FUNC(snsnew_state::snes21_hi_r),state), write8_delegate(FUNC(snsnew_state::snes21_hi_w),state));
2475//         machine.device("maincpu")->memory().space(AS_PROGRAM).install_read_handler(0x002800, 0x002800, 0, 0xbf0000, read8_delegate(FUNC(device_sns_cart_interface::chip_read),state->m_slotcart->m_cart));
2476//         machine.device("maincpu")->memory().space(AS_PROGRAM).install_write_handler(0x002801, 0x002801, 0, 0xbf0000, write8_delegate(FUNC(device_sns_cart_interface::chip_write),state->m_slotcart->m_cart));
2477//         set_5a22_map(*state->m_maincpu);
2557//          machine.device("maincpu")->memory().space(AS_PROGRAM).install_readwrite_handler(0x000000, 0x7dffff, read8_delegate(FUNC(snsnew_state::snes21_lo_r),state), write8_delegate(FUNC(snsnew_state::snes21_lo_w),state));
2558//          machine.device("maincpu")->memory().space(AS_PROGRAM).install_readwrite_handler(0x800000, 0xffffff, read8_delegate(FUNC(snsnew_state::snes21_hi_r),state), write8_delegate(FUNC(snsnew_state::snes21_hi_w),state));
2559//          machine.device("maincpu")->memory().space(AS_PROGRAM).install_read_handler(0x002800, 0x002800, 0, 0xbf0000, read8_delegate(FUNC(device_sns_cart_interface::chip_read),state->m_slotcart->m_cart));
2560//          machine.device("maincpu")->memory().space(AS_PROGRAM).install_write_handler(0x002801, 0x002801, 0, 0xbf0000, write8_delegate(FUNC(device_sns_cart_interface::chip_write),state->m_slotcart->m_cart));
2561//          set_5a22_map(*state->m_maincpu);
24782562         break;
24792563   }
24802564}
trunk/src/mess/machine/snescart.c
r21698r21699
128128}
129129
130130/* Saves the battery backed RAM from the appropriate memory area */
131static void snes_save_sram(running_machine &machine)
132{
133   snes_state *state = machine.driver_data<snes_state>();
134   device_image_interface *image = dynamic_cast<device_image_interface *>(machine.device("cart"));
135   image->battery_save(state->m_cart[0].m_nvram, state->m_cart[0].m_nvram_size);
136}
137
138131void snes_machine_stop(running_machine &machine)
139132{
140133   snes_state *state = machine.driver_data<snes_state>();
141134
142135   /* Save SRAM */
143136   if (state->m_cart[0].m_nvram_size > 0)
144      snes_save_sram(machine);
137   {
138      device_image_interface *image = dynamic_cast<device_image_interface *>(machine.device("cart"));
139      image->battery_save(state->m_cart[0].m_nvram, state->m_cart[0].m_nvram_size);
140   }
145141}
146142
147143
148144static void sufami_load_sram(running_machine &machine, const char *cart_tag)
149145{
150   UINT8 ii;
151   UINT8 *battery_ram, *ptr;
152   int st_sram_offset = 0;
153
154   battery_ram = (UINT8*)malloc(0x20000);
155   ptr = battery_ram;
146   snes_state *state = machine.driver_data<snes_state>();
147   int slot_id = 0;
156148   device_image_interface *image = dynamic_cast<device_image_interface *>(machine.device(cart_tag));
157   image->battery_load(battery_ram, 0x20000, 0);
158149
159150   if (strcmp(cart_tag, ":slot_a") == 0)
160      st_sram_offset = 0x608000;
151      slot_id = 0;
161152
162153   if (strcmp(cart_tag, ":slot_b") == 0)
163      st_sram_offset = 0x708000;
154      slot_id = 1;
164155
165   /* Cart RAM is at 0x60-0x63:0x8000-0xffff (+0x10 for slot2) */
166   for (ii = 0; ii < 4; ii++)
167   {
168      /* loading */
169      memcpy(&snes_ram[st_sram_offset + (ii * 0x010000)], ptr + (ii * 0x8000), 0x8000);
170      /* mirroring */
171      memcpy(&snes_ram[0x800000 + st_sram_offset + (ii * 0x010000)], &snes_ram[st_sram_offset + (ii * 0x010000)], 0x8000);
172   }
173
174   free(battery_ram);
156   image->battery_load(state->m_cart[slot_id].m_nvram, state->m_cart[slot_id].m_nvram_size, 0xff);
175157}
176158
177159void sufami_machine_stop(running_machine &machine)
178160{
179161   snes_state *state = machine.driver_data<snes_state>();
180   UINT8 ii;
181   UINT8 *battery_ram, *ptr;
182162
183   battery_ram = (UINT8*)malloc(0x20000);
184   ptr = battery_ram;
185
186   if (state->m_cart[0].slot_in_use)
163   if (state->m_cart[0].slot_in_use && state->m_cart[0].m_nvram_size)
187164   {
188      for (ii = 0; ii < 4; ii++)
189      {
190         memmove(ptr + ii * 0x8000, &snes_ram[0x608000 + (ii * 0x010000)], 0x8000);
191      }
192165      device_image_interface *image = dynamic_cast<device_image_interface *>(machine.device("slot_a"));
193      image->battery_save(battery_ram, 0x20000);
166      image->battery_save(state->m_cart[0].m_nvram, state->m_cart[0].m_nvram_size);
194167   }
195168
196   if (state->m_cart[1].slot_in_use)
169   if (state->m_cart[1].slot_in_use && state->m_cart[1].m_nvram_size)
197170   {
198      for (ii = 0; ii < 4; ii++)
199      {
200         memmove(ptr + ii * 0x8000, &snes_ram[0x708000 + (ii * 0x010000)], 0x8000);
201      }
202171      device_image_interface *image = dynamic_cast<device_image_interface *>(machine.device("slot_b"));
203      image->battery_save(battery_ram, 0x20000);
172      image->battery_save(state->m_cart[1].m_nvram, state->m_cart[1].m_nvram_size);
204173   }
205
206   free(battery_ram);
207174}
208175
209176
r21698r21699
594561   return supported_type;
595562}
596563
597static void snes_cart_log_info( running_machine &machine, UINT8* ROM, int total_blocks, int supported )
564static void snes_cart_log_info( running_machine &machine, UINT8* ROM, int supported )
598565{
599566   snes_state *state = machine.driver_data<snes_state>();
600567   device_image_interface *image = dynamic_cast<device_image_interface *>(machine.device("cart"));
r21698r21699
602569   int i, company, has_ram = 0, has_sram = 0;
603570   UINT32 offset = snes_skip_header(*image, state->m_cart_size);
604571   UINT32 hilo_mode = snes_find_hilo_mode(*image, ROM, offset, 0);
605   
572
606573   /* Company */
607574   for (i = 0; i < 2; i++)
608575      company_id[i] = ROM[hilo_mode - 0x10 + i];
r21698r21699
631598      ((ROM[hilo_mode + 0x16] & 0xf) == 6))
632599      has_sram = 1;
633600
601   int total_blocks = (state->m_cart[0].m_rom_size - offset) / (state->m_cart[0].mode & 0xa5 ? 0x8000 : 0x10000);
602
634603   logerror( "ROM DETAILS\n" );
635604   logerror( "===========\n\n" );
636605   logerror( "\tTotal blocks:  %d (%dmb)\n", total_blocks, total_blocks / (state->m_cart[0].mode & 5 ? 32 : 16) );
r21698r21699
662631   logerror( "\tVersion:       1.%d\n", ROM[hilo_mode + 0x1b] );
663632   logerror( "\tInv Checksum:  %X %X\n", ROM[hilo_mode + 0x1d], ROM[hilo_mode + 0x1c] );
664633   logerror( "\tChecksum:      %X %X\n", ROM[hilo_mode + 0x1f], ROM[hilo_mode + 0x1e] );
665   logerror( "\tNMI Address:   %2X%2Xh\n", ROM[hilo_mode + 0x3b], ROM[hilo_mode + 0x3a]);
666   logerror( "\tStart Address: %2X%2Xh\n\n", ROM[hilo_mode + 0x3d], ROM[hilo_mode + 0x3c]);
634   logerror( "\tNMI Address:   %2X%2Xh\n", ROM[hilo_mode + 0x3b], ROM[hilo_mode + 0x3a] );
635   logerror( "\tStart Address: %2X%2Xh\n\n", ROM[hilo_mode + 0x3d], ROM[hilo_mode + 0x3c] );
667636
668637   logerror( "\tMode: %d\n", state->m_cart[0].mode);
669638
r21698r21699
675644{
676645   int supported_type = 1;
677646   running_machine &machine = image.device().machine();
678   int total_blocks, read_blocks, has_bsx_slot = 0, st_bios = 0;
647   int has_bsx_slot = 0, st_bios = 0;
679648   UINT32 offset, int_header_offs;
680649   UINT8 *ROM = memregion("cart")->base();
681650
r21698r21699
700669   m_cart[0].m_rom_size = m_cart_size;
701670   m_cart[0].m_rom = auto_alloc_array_clear(machine, UINT8, m_cart[0].m_rom_size);
702671   memcpy(m_cart[0].m_rom, ROM, m_cart[0].m_rom_size - offset);
672   rom_map_setup(m_cart[0].m_rom_size);
703673
704674   /* First, look if the cart is HiROM or LoROM (and set snes_cart accordingly) */
705675   int_header_offs = snes_find_hilo_mode(image, ROM, offset, 0);
r21698r21699
760730
761731   if (SNES_CART_DEBUG) mame_printf_error("mode %d\n", m_cart[0].mode);
762732
763   /* FIXME: Insert crc check here? */
764
765   /* How many blocks of data are available to be loaded? */
766   total_blocks = ((m_cart_size - offset) / (m_cart[0].mode & 0xa5 ? 0x8000 : 0x10000));
767   read_blocks = 0;
768
769   if (SNES_CART_DEBUG) mame_printf_error("blocks %d\n", total_blocks);
770
771   /* Loading all the data blocks from cart, we only partially cover banks 0x00 to 0x7f. Therefore, we
772    * have to mirror the blocks until we reach the end. E.g. for a 11Mbits image (44 blocks), we proceed
773    * as follows:
774    * 11 Mbits = 8 Mbits (blocks 1->32) + 2 Mbits (blocks 33->40) + 1 Mbit (blocks 41->44).
775    * Hence, we fill memory up to 16 Mbits (banks 0x00 to 0x3f) mirroring as follows
776    * 8 Mbits (blocks 1->32) + 2 Mbits (blocks 33->40) + 1 Mbit (blocks 41->44) + 1 Mbit (blocks 41->44)
777    *   + 2 Mbits (blocks 33->40) + 1 Mbit (blocks 41->44) + 1 Mbit (blocks 41->44)
778    * and we repeat the same blocks in the second half of the banks (banks 0x40 to 0x7f).
779    * This is likely what happens in the real SNES as well, because the unit cannot be aware of the exact
780    * size of data in the cart (procedure confirmed by byuu)
781    */
782   switch (m_cart[0].mode)
783   {
784      case SNES_MODE_21:
785      /* HiROM carts load data in banks 0xc0 to 0xff. Each bank is fully mirrored in banks 0x40 to 0x7f
786       * (actually up to 0x7d, because 0x7e and 0x7f are overwritten by WRAM). The top half (address
787       * range 0x8000 - 0xffff) of each bank is also mirrored in banks 0x00 to 0x3f and 0x80 to 0xbf.
788       */
789         /* SPC7110 games needs this different loading routine */
790         if ((ROM[0x00ffd6] == 0xf9 || ROM[0x00ffd6] == 0xf5) && (ROM[0x00ffd5] == 0x3a))
791         {
792            while (read_blocks < 16 && read_blocks < total_blocks)
793            {
794               /* Loading data */
795               memcpy(&snes_ram[0xc00000 + read_blocks * 0x10000], &ROM[0x000000 + read_blocks * 0x10000], 0x10000);
796               /* Mirroring */
797               memcpy(&snes_ram[0x008000 + read_blocks * 0x10000], &snes_ram[0xc08000 + read_blocks * 0x10000], 0x8000);
798               memcpy(&snes_ram[0x808000 + read_blocks * 0x10000], &snes_ram[0xc08000 + read_blocks * 0x10000], 0x8000);
799               read_blocks++;
800            }
801         }
802         else
803         {
804            while (read_blocks < 64 && read_blocks < total_blocks)
805            {
806               /* Loading data */
807               memcpy(&snes_ram[0xc00000 + read_blocks * 0x10000], &ROM[0x000000 + read_blocks * 0x10000], 0x10000);
808               /* Mirroring */
809               memcpy(&snes_ram[0x008000 + read_blocks * 0x10000], &snes_ram[0xc08000 + read_blocks * 0x10000], 0x8000);
810               memcpy(&snes_ram[0x400000 + read_blocks * 0x10000], &snes_ram[0xc00000 + read_blocks * 0x10000], 0x10000);
811               memcpy(&snes_ram[0x808000 + read_blocks * 0x10000], &snes_ram[0xc08000 + read_blocks * 0x10000], 0x8000);
812               read_blocks++;
813            }
814            /* Filling banks up to 0xff and their mirrors */
815            while (read_blocks % 64)
816            {
817               int j = 0, repeat_blocks;
818               while ((read_blocks % (64 >> j)) && j < 6)
819                  j++;
820               repeat_blocks = read_blocks % (64 >> (j - 1));
821
822               memcpy(&snes_ram[0xc00000 + read_blocks * 0x10000], &snes_ram[0xc00000 + (read_blocks - repeat_blocks) * 0x10000], repeat_blocks * 0x10000);
823               memcpy(&snes_ram[read_blocks * 0x10000], &snes_ram[(read_blocks - repeat_blocks) * 0x10000], repeat_blocks * 0x10000);
824               memcpy(&snes_ram[0x400000 + read_blocks * 0x10000], &snes_ram[0x400000 + (read_blocks - repeat_blocks) * 0x10000], repeat_blocks * 0x10000);
825               memcpy(&snes_ram[0x800000 + read_blocks * 0x10000], &snes_ram[0x800000 + (read_blocks - repeat_blocks) * 0x10000], repeat_blocks * 0x10000);
826               read_blocks += repeat_blocks;
827            }
828         }
829         break;
830
831      case SNES_MODE_25:
832      /* Extendend HiROM carts start to load data in banks 0xc0 to 0xff. However, they exceed the
833       * available space in these banks, and continue loading at banks 0x40 to 0x7f. The top half
834       * (address range 0x8000 - 0xffff) of each bank is also mirrored either to banks 0x00 to 0x3f
835       * (for data in banks 0x40 to 0x7f) or to banks 0x80 to 0xbf (for data in banks 0xc0 to 0xff).
836       * Notice that banks 0x7e and 0x7f are overwritten by WRAM, but they could contain data at
837       * address > 0x8000 because the mirrors at 0x3e and 0x3f are not overwritten.
838       */
839         /* Reading the first 64 blocks */
840         while (read_blocks < 64 && read_blocks < total_blocks)
841         {
842            /* Loading data */
843            memcpy(&snes_ram[0xc00000 + read_blocks * 0x10000], &ROM[0x000000 + read_blocks * 0x10000], 0x10000);
844            /* Mirroring */
845            memcpy(&snes_ram[0x808000 + read_blocks * 0x10000], &snes_ram[0xc08000 + read_blocks * 0x10000], 0x8000);
846            read_blocks++;
847         }
848         /* ExHiROMs are supposed to be larger than 32Mbits! */
849         if (read_blocks < 64)
850         {
851            logerror("This image has been identified as ExHiROM, but it's too small!\n");
852            logerror("Please verify if it's corrupted. If it's not please report this as a bug.\n");
853            return IMAGE_INIT_FAIL;
854         }
855         /* Scaling down the counter */
856         read_blocks -= 64;
857         /* Reading the next blocks */
858         while (read_blocks < 64  && read_blocks < (total_blocks - 64))
859         {
860            /* Loading data */
861            memcpy(&snes_ram[0x400000 + read_blocks * 0x10000], &ROM[0x400000 + read_blocks * 0x10000], 0x10000);
862            /* Mirroring */
863            memcpy(&snes_ram[0x8000 + read_blocks * 0x10000], &snes_ram[0x408000 + read_blocks * 0x10000], 0x8000);
864            read_blocks++;
865         }
866         /* Filling banks up to 0x7f and their mirrors */
867         while (read_blocks % 64)
868         {
869            int j = 0, repeat_blocks;
870            while ((read_blocks % (64 >> j)) && j < 6)
871               j++;
872            repeat_blocks = read_blocks % (64 >> (j - 1));
873
874            memcpy(&snes_ram[0x400000 + read_blocks * 0x10000], &snes_ram[0x400000 + (read_blocks - repeat_blocks) * 0x10000], repeat_blocks * 0x10000);
875            memcpy(&snes_ram[read_blocks * 0x10000], &snes_ram[(read_blocks - repeat_blocks) * 0x10000], repeat_blocks * 0x10000);
876            read_blocks += repeat_blocks;
877         }
878         break;
879
880      case SNES_MODE_22:
881      /* "Extendend LoROM" carts have their data loaded in banks 0x00 to 0x3f at address 0x8000.
882       * These are then mirrored in banks 0x40 to 0x7f, both at address 0x0000 and at address
883       * 0x8000, in banks 0x80 to 0xbf at address 0x8000 and in banks 0xc0 to 0xff, both at address
884       * 0x0000 and at address 0x8000. Notice that SDD-1 games (Star Ocean and Street Fighter Zero 2)
885       * use SNES_MODE_22
886       */
887         while (read_blocks < 64 && read_blocks < total_blocks)
888         {
889            /* Loading and mirroring data */
890            memcpy(&snes_ram[0x008000 + read_blocks * 0x10000], &ROM[0x000000 + read_blocks * 0x8000], 0x8000);
891            memcpy(&snes_ram[0x808000 + read_blocks * 0x10000], &ROM[0x000000 + read_blocks * 0x8000], 0x8000);
892            memcpy(&snes_ram[0x400000 + read_blocks * 0x10000], &ROM[0x000000 + read_blocks * 0x10000], 0x10000);
893            memcpy(&snes_ram[0xc00000 + read_blocks * 0x10000], &ROM[0x000000 + read_blocks * 0x10000], 0x10000);
894            read_blocks++;
895         }
896         /* Filling banks up to 0x3f and their mirrors */
897         while (read_blocks % 64)
898         {
899            int j = 0, repeat_blocks;
900            while ((read_blocks % (64 >> j)) && j < 6)
901               j++;
902            repeat_blocks = read_blocks % (64 >> (j - 1));
903
904            memcpy(&snes_ram[read_blocks * 0x10000], &snes_ram[(read_blocks - repeat_blocks) * 0x10000], repeat_blocks * 0x10000);
905            memcpy(&snes_ram[0x800000 + read_blocks * 0x10000], &snes_ram[0x800000 + (read_blocks - repeat_blocks) * 0x10000], repeat_blocks * 0x10000);
906            memcpy(&snes_ram[0x400000 + read_blocks * 0x10000], &snes_ram[0x400000 + (read_blocks - repeat_blocks) * 0x10000], repeat_blocks * 0x10000);
907            memcpy(&snes_ram[0xc00000 + read_blocks * 0x10000], &snes_ram[0xc00000 + (read_blocks - repeat_blocks) * 0x10000], repeat_blocks * 0x10000);
908            read_blocks += repeat_blocks;
909         }
910         break;
911
912      case SNES_MODE_ST:
913         if (!st_bios)
914         {
915            mame_printf_error("This is a Sufami Turbo data cart and cannot be loaded for snes/snespal in MESS.\n");
916            mame_printf_error("Please use snesst driver to load it, instead.\n");
917            return IMAGE_INIT_FAIL;
918         }
919         else
920         {
921            // The Base ST cart consists of 8 * 0x8000 block which have to be loaded (and mirrored)
922            // at 0x00-0x1f:0x8000-0xffff and 0x80-0x9f:0x8000-0xffff
923            int i = 0;
924            for (i = 0; i < 8; i++)
925            {
926               /* Loading data */
927               memcpy(&snes_ram[0x008000 + i * 0x10000], &ROM[0x000000 + i * 0x8000], 0x8000);
928               /* Mirroring */
929               memcpy(&snes_ram[0x808000 + i * 0x10000], &snes_ram[0x8000 + (i * 0x10000)], 0x8000);
930
931               /* Additional mirrors (to fill snes_ram up to 0x1fffff) */
932               int j = 0;
933               for (j = 1; j < 4; j++)
934               {
935                  memcpy(&snes_ram[0x008000 + i * 0x10000 + j * 0x80000], &snes_ram[0x8000 + (i * 0x10000)], 0x8000);
936                  memcpy(&snes_ram[0x808000 + i * 0x10000 + j * 0x80000], &snes_ram[0x8000 + (i * 0x10000)], 0x8000);
937               }
938            }
939         }
940         break;
941
942      case SNES_MODE_BSX:
943      case SNES_MODE_BSLO:
944      case SNES_MODE_BSHI:
945         /* not handled yet */
946         mame_printf_error("This is a BS-X Satellaview image: MESS does not support these yet, sorry.\n");
947         /* so treat it like MODE_20 */
948         m_cart[0].mode = SNES_MODE_20;
949         /* and load it as such... */
950
951      default:
952      case SNES_MODE_20:
953      /* LoROM carts load data in banks 0x00 to 0x7f at address 0x8000 (actually up to 0x7d, because 0x7e and
954       * 0x7f are overwritten by WRAM). Each block is also mirrored in banks 0x80 to 0xff (up to 0xff for real)
955       */
956         /* SuperFX games needs this different loading routine */
957         if (((ROM[0x007fd6] >= 0x13 && ROM[0x007fd6] <= 0x15) || ROM[0x007fd6] == 0x1a) && (ROM[0x007fd5] == 0x20))
958         {
959            while (read_blocks < 64 && read_blocks < total_blocks)
960            {
961               /* Loading data primary: banks 0-3f from 8000-ffff*/
962               memcpy(&snes_ram[0x008000 + read_blocks * 0x10000], &ROM[0x000000 + read_blocks * 0x8000], 0x8000);
963               /* Mirroring at banks 80-bf from 8000-ffff */
964               memcpy(&snes_ram[0x808000 + read_blocks * 0x10000], &snes_ram[0x8000 + (read_blocks * 0x10000)], 0x8000);
965               /* Mirroring at banks 40-5f and c0-df */
966               memcpy(&snes_ram[0x400000 + read_blocks * 0x8000], &snes_ram[0x8000 + (read_blocks * 0x10000)], total_blocks * 0x8000);
967               memcpy(&snes_ram[0xc00000 + read_blocks * 0x8000], &snes_ram[0x8000 + (read_blocks * 0x10000)], total_blocks * 0x8000);
968
969               read_blocks++;
970            }
971            /* SuperFX games are supposed to contain 64 blocks! */
972            if (read_blocks < total_blocks)
973            {
974               logerror("This image has been identified as a SuperFX game, but it's too large!\n");
975               logerror("Please verify if it's corrupted. If it's not please report this as a bug.\n");
976               return IMAGE_INIT_FAIL;
977            }
978         }
979         else
980         {
981            while (read_blocks < 128 && read_blocks < total_blocks)
982            {
983               /* Loading data */
984               memcpy(&snes_ram[0x008000 + read_blocks * 0x10000], &ROM[0x000000 + read_blocks * 0x8000], 0x8000);
985               /* Mirroring */
986               memcpy(&snes_ram[0x808000 + read_blocks * 0x10000], &snes_ram[0x8000 + (read_blocks * 0x10000)], 0x8000);
987               read_blocks++;
988            }
989            /* Filling banks up to 0x7f and their mirrors */
990            while (read_blocks % 128)
991            {
992               int j = 0, repeat_blocks;
993               while ((read_blocks % (128 >> j)) && j < 7)
994                  j++;
995               repeat_blocks = read_blocks % (128 >> (j - 1));
996
997               memcpy(&snes_ram[read_blocks * 0x10000], &snes_ram[(read_blocks - repeat_blocks) * 0x10000], repeat_blocks * 0x10000);
998               memcpy(&snes_ram[0x800000 + read_blocks * 0x10000], &snes_ram[(read_blocks - repeat_blocks) * 0x10000], repeat_blocks * 0x10000);
999               read_blocks += repeat_blocks;
1000            }
1001         }
1002         break;
1003   }
1004
1005733   /* Detect special chips */
1006734   supported_type = snes_find_addon_chip(machine, ROM, int_header_offs);
1007735
r21698r21699
1013741      if ((m_has_addon_chip != HAS_SUPERFX))
1014742         nvram_size = ROM[int_header_offs + 0x18];
1015743      else
1016         nvram_size = (ROM[0x00ffbd] & 0x07);
744         nvram_size = (ROM[0x007fbd] & 0x07);
1017745
1018746      if (nvram_size > 0)
1019747      {
r21698r21699
1044772      m_cart[0].m_nvram = auto_alloc_array_clear(machine, UINT8, m_cart[0].m_nvram_size);
1045773
1046774   /* Log snes_cart information */
1047   snes_cart_log_info(machine, ROM, total_blocks, supported_type);
775   snes_cart_log_info(machine, ROM, supported_type);
1048776
1049777   /* Load SRAM */
1050778   if (m_cart[0].m_nvram_size > 0)
r21698r21699
1057785DEVICE_IMAGE_LOAD_MEMBER( snes_state,sufami_cart )
1058786{
1059787   running_machine &machine = image.device().machine();
1060   int total_blocks, read_blocks;
1061788   int st_bios = 0, slot_id = 0;
1062   UINT32 offset, st_data_offset = 0;
789   UINT32 offset;
1063790   UINT8 *ROM = image.device().machine().root_device().memregion(image.device().tag())->base();
1064791
1065   snes_ram = memregion("maincpu")->base();
1066
1067792   if (strcmp(image.device().tag(), ":slot_a") == 0)
1068   {
1069      st_data_offset = 0x200000;
1070793      slot_id = 0;
1071   }
1072794
1073795   if (strcmp(image.device().tag(), ":slot_b") == 0)
1074   {
1075      st_data_offset = 0x400000;
1076796      slot_id = 1;
1077   }
1078797
1079798   if (image.software_entry() == NULL)
1080799      m_cart_size = image.length();
r21698r21699
1115834      return IMAGE_INIT_FAIL;
1116835   }
1117836
1118   /* FIXME: Insert crc check here? */
1119837
1120   /* How many blocks of data are available to be loaded? */
1121   total_blocks = (m_cart_size - offset) / 0x8000;
1122   read_blocks = 0;
838   m_cart[slot_id].m_rom_size = m_cart_size;
839   m_cart[slot_id].m_rom = auto_alloc_array_clear(machine, UINT8, m_cart[0].m_rom_size);
840   memcpy(m_cart[slot_id].m_rom, ROM, m_cart[slot_id].m_rom_size - offset);
841   rom_map_setup(m_cart[slot_id].m_rom_size);
1123842
1124   if (SNES_CART_DEBUG)
1125      mame_printf_error("blocks %d\n", total_blocks);
843   m_cart[slot_id].m_nvram_size = 0x20000;
844   m_cart[slot_id].m_nvram = auto_alloc_array_clear(machine, UINT8, m_cart[slot_id].m_nvram_size);
1126845
1127   // actually load the cart
1128   while (read_blocks < 32 && read_blocks < total_blocks)
1129   {
1130      /* Loading data */
1131      // CART (either A or B)
1132      memcpy(&snes_ram[0x008000 + st_data_offset + read_blocks * 0x10000], &ROM[0x000000 + read_blocks * 0x8000], 0x8000);
1133      /* Mirroring */
1134      memcpy(&snes_ram[0x808000 + st_data_offset + read_blocks * 0x10000], &snes_ram[0x8000 + st_data_offset + (read_blocks * 0x10000)], 0x8000);
1135
1136      read_blocks++;
1137   }
1138
1139   /* Filling banks up to 0x1f and their mirrors */
1140   while (read_blocks % 32)
1141   {
1142      int j = 0, repeat_blocks;
1143      while ((read_blocks % (32 >> j)) && j < 5)
1144         j++;
1145      repeat_blocks = read_blocks % (32 >> (j - 1));
1146
1147      memcpy(&snes_ram[st_data_offset + read_blocks * 0x10000], &snes_ram[st_data_offset + (read_blocks - repeat_blocks) * 0x10000], repeat_blocks * 0x10000);
1148      memcpy(&snes_ram[0x800000 + st_data_offset + read_blocks * 0x10000], &snes_ram[st_data_offset + (read_blocks - repeat_blocks) * 0x10000], repeat_blocks * 0x10000);
1149      read_blocks += repeat_blocks;
1150   }
1151
1152   // currently we still use snes_ram for STROM ram...
1153//  m_cart[slot_id].m_nvram_size = 0x20000;
1154//  m_cart[slot_id].m_nvram = auto_alloc_array_clear(machine, UINT8, m_cart[slot_id].m_nvram_size);
1155   m_cart[slot_id].m_nvram_size = 0;
1156
1157846   sufami_load_sram(machine, image.device().tag());
1158847
1159848   m_cart[slot_id].slot_in_use = 1; // aknowledge the cart in this slot, for saving sram at exit
1160849
1161   auto_free(image.device().machine(), ROM);
1162
1163850   return IMAGE_INIT_PASS;
1164851}
1165852
r21698r21699
1212899
1213900DRIVER_INIT_MEMBER(snes_state,snesst)
1214901{
1215   UINT8 *STBIOS = memregion("sufami")->base();
1216   int i, j;
1217
1218902   m_cart[0].slot_in_use = 0;
1219903   m_cart[1].slot_in_use = 0;
1220904
1221905   DRIVER_INIT_CALL(snes_mess);
1222
1223   // the Base ST cart consists of 8 * 0x8000 block which have to be loaded (and mirrored)
1224   // at 0x00-0x1f:0x8000-0xffff and 0x80-0x9f:0x8000-0xffff
1225   for (i = 0; i < 8; i++)
1226   {
1227      /* Loading data */
1228      memcpy(&snes_ram[0x008000 + i * 0x10000], &STBIOS[0x000000 + i * 0x8000], 0x8000);
1229      /* Mirroring */
1230      memcpy(&snes_ram[0x808000 + i * 0x10000], &snes_ram[0x8000 + (i * 0x10000)], 0x8000);
1231
1232      /* Additional mirrors (to fill snes_ram up to 0x1fffff) */
1233      for (j = 1; j < 4; j++)
1234      {
1235         memcpy(&snes_ram[0x008000 + i * 0x10000 + j * 0x80000], &snes_ram[0x8000 + (i * 0x10000)], 0x8000);
1236         memcpy(&snes_ram[0x808000 + i * 0x10000 + j * 0x80000], &snes_ram[0x8000 + (i * 0x10000)], 0x8000);
1237      }
1238   }
1239
1240906}
1241907
1242908// add-on chip emulators

Previous 199869 Revisions Next


© 1997-2024 The MAME Team