Previous 199869 Revisions Next

r20931 Monday 11th February, 2013 at 10:13:14 UTC by Fabio Priuli
(MESS) nes.c: shuffled around the loading code (very preliminary step towards slotification).
also, temporarily made famicom driver to only support disks.
[src/mess]mess.mak
[src/mess/drivers]nes.c
[src/mess/includes]nes.h nes_mmc.h
[src/mess/machine]nes.c nes_mmc.c nes_slot.c* nes_slot.h* nes_unif.c

trunk/src/mess/machine/nes.c
r20930r20931
4242{
4343   address_space &space = machine().device("maincpu")->memory().space(AS_PROGRAM);
4444   static const char *const bank_names[] = { "bank1", "bank2", "bank3", "bank4" };
45   int prg_banks = (m_prg_chunks == 1) ? (2 * 2) : (m_prg_chunks * 2);
4645   int i;
46   m_prg_chunks = 0;
47   m_chr_chunks = 0;
48   m_vram_chunks = 0;
49   m_pcb_id = NO_BOARD;
4750
4851   m_rom = machine().root_device().memregion("maincpu")->base();
4952   m_ciram = machine().root_device().memregion("ciram")->base();
r20930r20931
5760
5861   membank("bank10")->set_base(m_rom);
5962
63   // get cart info from cartslot
64   if (m_cartslot && m_cartslot->m_cart)
65   {
66      m_prg_chunks = m_cartslot->m_cart->get_prg_size() / 0x4000;
67      m_chr_chunks = m_cartslot->m_cart->get_vrom_size() / 0x2000;
68      m_vram_chunks = m_cartslot->m_cart->get_vram_size() / 0x2000;
69//      printf("%d - %d - %d\n", m_prg_chunks, m_chr_chunks, m_vram_chunks);
70      m_prg = m_cartslot->m_cart->get_prg_base();
71      if (m_cartslot->m_cart->get_vrom_size())
72         m_vrom = m_cartslot->m_cart->get_vrom_base();
73      if (m_cartslot->m_cart->get_vram_size())
74         m_vram = auto_alloc_array(machine(), UINT8, m_cartslot->m_cart->get_vram_size());
75     
76      m_pcb_id = m_cartslot->get_pcb_id();
77      m_hard_mirroring = m_cartslot->m_cart->get_mirroring();
78      m_four_screen_vram = m_cartslot->m_cart->get_four_screen_vram();
79     
80      // setup memory pointers and related variables
81      m_prg_ram = m_cartslot->m_cart->get_battery_size() ? 1 : 0;
82      m_wram_size = m_cartslot->m_cart->get_prgram_size();
83      m_mapper_ram_size = m_cartslot->m_cart->get_mapper_ram_size();
84      m_mapper_bram_size = m_cartslot->m_cart->get_mapper_bram_size();
85      m_battery = m_cartslot->m_cart->get_battery_size() ? 1 : 0;
86      m_battery_size = m_cartslot->m_cart->get_battery_size();
87     
88      if (m_prg_ram)
89         m_wram = m_cartslot->m_cart->get_prgram_base();
90      if (m_mapper_ram_size)
91         m_mapper_ram = m_cartslot->m_cart->get_mapper_ram_base();
92      if (m_battery)
93         m_battery_ram = m_cartslot->m_cart->get_battery_base();
94      if (m_mapper_bram_size)
95         m_mapper_bram = m_cartslot->m_cart->get_mapper_bram_base();
96     
97      // setup the rest of the variables involved
98      m_chr_open_bus = m_cartslot->get_chr_open_bus();
99      m_ce_mask = m_cartslot->get_ce_mask();
100      m_ce_state = m_cartslot->get_ce_state();
101      m_vrc_ls_prg_a = m_cartslot->get_vrc_ls_prg_a();
102      m_vrc_ls_prg_b = m_cartslot->get_vrc_ls_prg_b();
103      m_vrc_ls_chr = m_cartslot->get_vrc_ls_chr();
104      m_crc_hack = m_cartslot->get_crc_hack();
105   }
106
107   int prg_banks = (m_prg_chunks == 1) ? (2 * 2) : (m_prg_chunks * 2);
108
60109   /* If there is Disk Expansion and no cart has been loaded, setup memory accordingly */
61110   if (m_disk_expansion && m_pcb_id == NO_BOARD)
62111   {
r20930r20931
83132      membank("bank2")->set_base(m_fds_ram);
84133      return;
85134   }
86
87   /* Set up the mapper callbacks */
88   pcb_handlers_setup();
89
90   /* Set up the memory handlers for the mapper */
91   space.install_read_bank(0x8000, 0x9fff, "bank1");
92   space.install_read_bank(0xa000, 0xbfff, "bank2");
93   space.install_read_bank(0xc000, 0xdfff, "bank3");
94   space.install_read_bank(0xe000, 0xffff, "bank4");
95   space.install_readwrite_bank(0x6000, 0x7fff, "bank5");
96
97   /* configure banks 1-4 */
98   for (i = 0; i < 4; i++)
99   {
100      membank(bank_names[i])->configure_entries(0, prg_banks, m_prg, 0x2000);
101      // some mappers (e.g. MMC5) can map PRG RAM in  0x8000-0xffff as well
102      if (m_prg_ram)
103         membank(bank_names[i])->configure_entries(prg_banks, m_wram_size / 0x2000, m_wram, 0x2000);
104      // however, at start we point to PRG ROM
105      membank(bank_names[i])->set_entry(i);
106      m_prg_bank[i] = i;
107   }
108
109   /* bank 5 configuration is more delicate, since it can have PRG RAM, PRG ROM or SRAM mapped to it */
110   /* we first map PRG ROM banks, then the battery bank (if a battery is present), and finally PRG RAM (m_wram) */
111   membank("bank5")->configure_entries(0, prg_banks, m_prg, 0x2000);
112   m_battery_bank5_start = prg_banks;
113   m_prgram_bank5_start = prg_banks;
114   m_empty_bank5_start = prg_banks;
115
116   /* add battery ram, but only if there's no trainer since they share overlapping memory. */
117   if (m_battery && !m_trainer)
118   {
119      UINT32 bank_size = (m_battery_size > 0x2000) ? 0x2000 : m_battery_size;
120      int bank_num = (m_battery_size > 0x2000) ? m_battery_size / 0x2000 : 1;
121      membank("bank5")->configure_entries(prg_banks, bank_num, m_battery_ram, bank_size);
122      m_prgram_bank5_start += bank_num;
123      m_empty_bank5_start += bank_num;
124   }
125   /* add prg ram. */
126   if (m_prg_ram)
127   {
128      membank("bank5")->configure_entries(m_prgram_bank5_start, m_wram_size / 0x2000, m_wram, 0x2000);
129      m_empty_bank5_start += m_wram_size / 0x2000;
130   }
131
132   membank("bank5")->configure_entry(m_empty_bank5_start, m_rom + 0x6000);
133
134   /* if we have any additional PRG RAM, point bank5 to its first bank */
135   if (m_battery || m_prg_ram)
136      m_prg_bank[4] = m_battery_bank5_start;
137135   else
138      m_prg_bank[4] = m_empty_bank5_start; // or shall we point to "maincpu" region at 0x6000? point is that we should never access this region if no sram or wram is present!
139
140   membank("bank5")->set_entry(m_prg_bank[4]);
141
142   if (m_four_screen_vram)
143136   {
144      m_extended_ntram = auto_alloc_array_clear(machine(), UINT8, 0x2000);
145      save_pointer(NAME(m_extended_ntram), 0x2000);
146   }
147
148   if (m_four_screen_vram)
149      set_nt_mirroring(PPU_MIRROR_4SCREEN);
150   else
151   {
152      switch (m_hard_mirroring)
137      /* Set up the mapper callbacks */
138      pcb_handlers_setup();
139     
140      /* Set up the memory handlers for the mapper */
141      space.install_read_bank(0x8000, 0x9fff, "bank1");
142      space.install_read_bank(0xa000, 0xbfff, "bank2");
143      space.install_read_bank(0xc000, 0xdfff, "bank3");
144      space.install_read_bank(0xe000, 0xffff, "bank4");
145      space.install_readwrite_bank(0x6000, 0x7fff, "bank5");
146     
147      /* configure banks 1-4 */
148      for (i = 0; i < 4; i++)
153149      {
154         case PPU_MIRROR_HORZ:
155         case PPU_MIRROR_VERT:
156         case PPU_MIRROR_HIGH:
157         case PPU_MIRROR_LOW:
158            set_nt_mirroring(m_hard_mirroring);
159            break;
160         default:
161            set_nt_mirroring(PPU_MIRROR_NONE);
162            break;
150         membank(bank_names[i])->configure_entries(0, prg_banks, m_prg, 0x2000);
151         // some mappers (e.g. MMC5) can map PRG RAM in  0x8000-0xffff as well
152         if (m_prg_ram)
153            membank(bank_names[i])->configure_entries(prg_banks, m_wram_size / 0x2000, m_wram, 0x2000);
154         // however, at start we point to PRG ROM
155         membank(bank_names[i])->set_entry(i);
156         m_prg_bank[i] = i;
163157      }
158     
159      /* bank 5 configuration is more delicate, since it can have PRG RAM, PRG ROM or SRAM mapped to it */
160      /* we first map PRG ROM banks, then the battery bank (if a battery is present), and finally PRG RAM (m_wram) */
161      membank("bank5")->configure_entries(0, prg_banks, m_prg, 0x2000);
162      m_battery_bank5_start = prg_banks;
163      m_prgram_bank5_start = prg_banks;
164      m_empty_bank5_start = prg_banks;
165     
166      /* add battery ram, but only if there's no trainer since they share overlapping memory. */
167      if (m_battery && !m_trainer)
168      {
169         UINT32 bank_size = (m_battery_size > 0x2000) ? 0x2000 : m_battery_size;
170         int bank_num = (m_battery_size > 0x2000) ? m_battery_size / 0x2000 : 1;
171         membank("bank5")->configure_entries(prg_banks, bank_num, m_battery_ram, bank_size);
172         m_prgram_bank5_start += bank_num;
173         m_empty_bank5_start += bank_num;
174      }
175      /* add prg ram. */
176      if (m_prg_ram)
177      {
178         membank("bank5")->configure_entries(m_prgram_bank5_start, m_wram_size / 0x2000, m_wram, 0x2000);
179         m_empty_bank5_start += m_wram_size / 0x2000;
180      }
181     
182      membank("bank5")->configure_entry(m_empty_bank5_start, m_rom + 0x6000);
183     
184      /* if we have any additional PRG RAM, point bank5 to its first bank */
185      if (m_battery || m_prg_ram)
186         m_prg_bank[4] = m_battery_bank5_start;
187      else
188         m_prg_bank[4] = m_empty_bank5_start; // or shall we point to "maincpu" region at 0x6000? point is that we should never access this region if no sram or wram is present!
189     
190      membank("bank5")->set_entry(m_prg_bank[4]);
191     
192      if (m_four_screen_vram)
193      {
194         m_extended_ntram = auto_alloc_array_clear(machine(), UINT8, 0x2000);
195         save_pointer(NAME(m_extended_ntram), 0x2000);
196      }
197     
198      if (m_four_screen_vram)
199         set_nt_mirroring(PPU_MIRROR_4SCREEN);
200      else
201      {
202         switch (m_hard_mirroring)
203         {
204            case PPU_MIRROR_HORZ:
205            case PPU_MIRROR_VERT:
206            case PPU_MIRROR_HIGH:
207            case PPU_MIRROR_LOW:
208               set_nt_mirroring(m_hard_mirroring);
209               break;
210            default:
211               set_nt_mirroring(PPU_MIRROR_NONE);
212               break;
213         }
214      }
164215   }
165216
166217   // there are still some quirk about writes to bank5... I hope to fix them soon. (mappers 34,45,52,246 have both mid_w and WRAM-->check)
218   if (!m_mmc_write_low.isnull())
219      space.install_write_handler(0x4100, 0x5fff, m_mmc_write_low);
167220   if (!m_mmc_write_mid.isnull())
168221      space.install_write_handler(0x6000, 0x7fff, m_mmc_write_mid);
169222   if (!m_mmc_write.isnull())
r20930r20931
172225   // In fact, we also allow single pcbs to overwrite the bank read handlers defined above,
173226   // because some pcbs (mainly pirate ones) require protection values to be read instead of
174227   // the expected ROM banks: these handlers, though, must take care of the ROM access as well
228   if (!m_mmc_read_low.isnull())
229      space.install_read_handler(0x4100, 0x5fff, m_mmc_read_low);
175230   if (!m_mmc_read_mid.isnull())
176231      space.install_read_handler(0x6000, 0x7fff, m_mmc_read_mid);
177232   if (!m_mmc_read.isnull())
r20930r20931
302357
303358   m_maincpu           = machine().device<cpu_device>("maincpu");
304359   m_sound             = machine().device("nessound");
305   m_cart              = machine().device("cart");
306360   m_io_ctrlsel        = ioport("CTRLSEL");
307361   m_io_fckey[0]       = ioport("FCKEY0");
308362   m_io_fckey[1]       = ioport("FCKEY1");
r20930r20931
364418
365419
366420//-------------------------------------------------
367//  machine_stop
368//-------------------------------------------------
369
370void nes_state::machine_stop()
371{
372   device_image_interface *image = dynamic_cast<device_image_interface *>(m_cart);
373   /* Write out the battery file if necessary */
374   if (m_battery)
375      image->battery_save(m_battery_ram, m_battery_size);
376
377   if (m_mapper_bram_size)
378      image->battery_save(m_mapper_bram, m_mapper_bram_size);
379}
380
381
382
383//-------------------------------------------------
384421//  update_prg_banks
385422//-------------------------------------------------
386423
r20930r20931
670707{
671708}
672709
673struct nes_cart_lines
674{
675   const char *tag;
676   int line;
677};
678710
679static const struct nes_cart_lines nes_cart_lines_table[] =
680{
681   { "PRG A0",    0 },
682   { "PRG A1",    1 },
683   { "PRG A2",    2 },
684   { "PRG A3",    3 },
685   { "PRG A4",    4 },
686   { "PRG A5",    5 },
687   { "PRG A6",    6 },
688   { "PRG A7",    7 },
689   { "CHR A10",  10 },
690   { "CHR A11",  11 },
691   { "CHR A12",  12 },
692   { "CHR A13",  13 },
693   { "CHR A14",  14 },
694   { "CHR A15",  15 },
695   { "CHR A16",  16 },
696   { "CHR A17",  17 },
697   { "NC",      127 },
698   { 0 }
699};
700711
701static int nes_cart_get_line( const char *feature )
702{
703   const struct nes_cart_lines *nes_line = &nes_cart_lines_table[0];
704
705   if (feature == NULL)
706      return 128;
707
708   while (nes_line->tag)
709   {
710      if (strcmp(nes_line->tag, feature) == 0)
711         break;
712
713      nes_line++;
714   }
715
716   return nes_line->line;
717}
718
719DEVICE_IMAGE_LOAD_MEMBER( nes_state, nes_cart )
720{
721   nes_state *state = image.device().machine().driver_data<nes_state>();
722   state->m_pcb_id = NO_BOARD; // initialization
723
724   if (image.software_entry() == NULL)
725   {
726      const char *mapinfo = NULL;
727      int mapint1 = 0, mapint2 = 0, mapint3 = 0, mapint4 = 0; //, goodcrcinfo = 0;
728      char magic[4], extend[5];
729      int local_options = 0;
730      char m;
731
732      /* Check first 4 bytes of the image to decide if it is UNIF or iNES */
733      /* Unfortunately, many .unf files have been released as .nes, so we cannot rely on extensions only */
734      memset(magic, '\0', sizeof(magic));
735      image.fread(magic, 4);
736
737      if ((magic[0] == 'N') && (magic[1] == 'E') && (magic[2] == 'S'))    /* If header starts with 'NES' it is iNES */
738      {
739         UINT32 prg_size;
740         state->m_ines20 = 0;
741         state->m_battery_size = NES_BATTERY_SIZE; // with iNES we can only support 8K WRAM battery (iNES 2.0 might fix this)
742         state->m_prg_ram = 1;   // always map state->m_wram in bank5 (eventually, this should be enabled only for some mappers)
743
744         // check if the image is recognized by nes.hsi
745         mapinfo = hashfile_extrainfo(image);
746
747         // image_extrainfo() resets the file position back to start.
748         // Let's skip past the magic header once again.
749         image.fseek(4, SEEK_SET);
750
751         image.fread(&state->m_prg_chunks, 1);
752         image.fread(&state->m_chr_chunks, 1);
753         /* Read the first ROM option byte (offset 6) */
754         image.fread(&m, 1);
755
756         /* Interpret the iNES header flags */
757         state->m_mapper = (m & 0xf0) >> 4;
758         local_options = m & 0x0f;
759
760         /* Read the second ROM option byte (offset 7) */
761         image.fread(&m, 1);
762
763         switch (m & 0xc)
764         {
765            case 0x4:
766            case 0xc:
767               // probably the header got corrupted: don't trust upper bits for mapper
768               break;
769
770            case 0x8:   // it's iNES 2.0 format
771               state->m_ines20 = 1;
772            case 0x0:
773            default:
774               state->m_mapper = state->m_mapper | (m & 0xf0);
775               break;
776         }
777
778         if (mapinfo /* && !state->m_ines20 */)
779         {
780            if (4 == sscanf(mapinfo,"%d %d %d %d", &mapint1, &mapint2, &mapint3, &mapint4))
781            {
782               /* image is present in nes.hsi: overwrite the header settings with these */
783               state->m_mapper = mapint1;
784               local_options = mapint2 & 0x0f;
785               state->m_crc_hack = (mapint2 & 0xf0) >> 4;  // this is used to differentiate among variants of the same Mapper (see below)
786               state->m_prg_chunks = mapint3;
787               state->m_chr_chunks = mapint4;
788               logerror("NES.HSI info: %d %d %d %d\n", mapint1, mapint2, mapint3, mapint4);
789//                  mame_printf_error("NES.HSI info: %d %d %d %d\n", mapint1, mapint2, mapint3, mapint4);
790//                  goodcrcinfo = 1;
791               state->m_ines20 = 0;
792            }
793            else
794            {
795               logerror("NES: [%s], Invalid mapinfo found\n", mapinfo);
796            }
797         }
798         else
799         {
800            logerror("NES: No extrainfo found\n");
801         }
802
803         state->m_hard_mirroring = (local_options & 0x01) ? PPU_MIRROR_VERT : PPU_MIRROR_HORZ;
804//          mame_printf_error("%s\n", state->m_hard_mirroring & 0x01 ? "Vertical" : "Horizontal");
805         state->m_battery = local_options & 0x02;
806         state->m_trainer = local_options & 0x04;
807         state->m_four_screen_vram = local_options & 0x08;
808
809         if (state->m_battery)
810            logerror("-- Battery found\n");
811
812         if (state->m_trainer)
813            logerror("-- Trainer found\n");
814
815         if (state->m_four_screen_vram)
816            logerror("-- 4-screen VRAM\n");
817
818         if (state->m_ines20)
819         {
820            logerror("Extended iNES format:\n");
821            image.fread(&extend, 5);
822            state->m_mapper |= (extend[0] & 0x0f) << 8;
823            logerror("-- mapper: %d\n", state->m_mapper);
824            logerror("-- submapper: %d\n", (extend[0] & 0xf0) >> 4);
825            state->m_prg_chunks |= ((extend[1] & 0x0f) << 8);
826            state->m_chr_chunks |= ((extend[1] & 0xf0) << 4);
827            logerror("-- PRG chunks: %d\n", state->m_prg_chunks);
828            logerror("-- CHR chunks: %d\n", state->m_chr_chunks);
829            logerror("-- PRG NVWRAM: %d\n", extend[2] & 0x0f);
830            logerror("-- PRG WRAM: %d\n", (extend[2] & 0xf0) >> 4);
831            logerror("-- CHR NVWRAM: %d\n", extend[3] & 0x0f);
832            logerror("-- CHR WRAM: %d\n", (extend[3] & 0xf0) >> 4);
833            logerror("-- TV System: %d\n", extend[4] & 3);
834         }
835
836         // Allocate class pointers for PRG/VROM/VRAM/WRAM
837         prg_size = (state->m_prg_chunks == 1) ? 2 * 0x4000 : state->m_prg_chunks * 0x4000;
838         state->m_prg = auto_alloc_array(image.device().machine(), UINT8, prg_size);
839         if (state->m_chr_chunks)
840            state->m_vrom = auto_alloc_array(image.device().machine(), UINT8, state->m_chr_chunks * 0x2000);
841
842         state->m_vram_chunks = 2;
843         state->m_vram = auto_alloc_array(image.device().machine(), UINT8, 0x4000);
844
845         // FIXME: this should only be allocated if there is actual wram in the cart (i.e. if state->m_prg_ram = 1)!
846         // or if there is a trainer, I think
847         state->m_wram_size = 0x10000;
848         state->m_wram = auto_alloc_array(image.device().machine(), UINT8, state->m_wram_size);
849
850         /* Setup PCB type (needed to add proper handlers later) */
851         state->m_pcb_id = nes_get_mmc_id(image.device().machine(), state->m_mapper);
852
853         // a few mappers correspond to multiple PCBs, so we need a few additional checks
854         switch (state->m_pcb_id)
855         {
856            case STD_CNROM:
857               if (state->m_mapper == 185)
858               {
859                  switch (state->m_crc_hack)
860                  {
861                     case 0x0: // pin26: CE, pin27: CE (B-Wings, Bird Week)
862                        state->m_ce_mask = 0x03;
863                        state->m_ce_state = 0x03;
864                        break;
865                     case 0x4: // pin26: CE, pin27: /CE (Mighty Bomb Jack, Spy Vs. Spy)
866                        state->m_ce_mask = 0x03;
867                        state->m_ce_state = 0x01;
868                        break;
869                     case 0x8: // pin26: /CE, pin27: CE (Sansu 1, 2, 3 Nen)
870                        state->m_ce_mask = 0x03;
871                        state->m_ce_state = 0x02;
872                        break;
873                     case 0xc: // pin26: /CE, pin27: /CE (Seicross v2.0)
874                        state->m_ce_mask = 0x03;
875                        state->m_ce_state = 0x00;
876                        break;
877                  }
878               }
879               break;
880            case KONAMI_VRC2:
881               if (state->m_mapper == 22)
882               {
883                  state->m_vrc_ls_prg_a = 0;
884                  state->m_vrc_ls_prg_b = 1;
885                  state->m_vrc_ls_chr = 1;
886               }
887               if (state->m_mapper == 23 && !state->m_crc_hack)
888               {
889                  state->m_vrc_ls_prg_a = 1;
890                  state->m_vrc_ls_prg_b = 0;
891                  state->m_vrc_ls_chr = 0;
892               }
893               if (state->m_mapper == 23 && state->m_crc_hack)
894               {
895                  // here there are also Akumajou Special, Crisis Force, Parodius da!, Tiny Toons which are VRC-4
896                  state->m_vrc_ls_prg_a = 3;
897                  state->m_vrc_ls_prg_b = 2;
898                  state->m_pcb_id = KONAMI_VRC4; // this allows for konami_irq to be installed at reset
899               }
900               break;
901            case KONAMI_VRC4:
902               if (state->m_mapper == 21)
903               {
904                  // Wai Wai World 2 & Ganbare Goemon Gaiden 2 (the latter with crc_hack)
905                  state->m_vrc_ls_prg_a = state->m_crc_hack ? 7 : 2;
906                  state->m_vrc_ls_prg_b = state->m_crc_hack ? 6 : 1;
907               }
908               if (state->m_mapper == 25)  // here there is also Ganbare Goemon Gaiden which is VRC-2
909               {
910                  state->m_vrc_ls_prg_a = state->m_crc_hack ? 2 : 0;
911                  state->m_vrc_ls_prg_b = state->m_crc_hack ? 3 : 1;
912               }
913               break;
914            case KONAMI_VRC6:
915               if (state->m_mapper == 24)
916               {
917                  state->m_vrc_ls_prg_a = 1;
918                  state->m_vrc_ls_prg_b = 0;
919               }
920               if (state->m_mapper == 26)
921               {
922                  state->m_vrc_ls_prg_a = 0;
923                  state->m_vrc_ls_prg_b = 1;
924               }
925               break;
926            case IREM_G101:
927               if (state->m_crc_hack)
928                  state->m_hard_mirroring = PPU_MIRROR_HIGH;  // Major League has hardwired mirroring
929               break;
930            case DIS_74X161X161X32:
931               if (state->m_mapper == 70)
932                  state->m_hard_mirroring = PPU_MIRROR_VERT;  // only hardwired mirroring makes different mappers 70 & 152
933               break;
934            case SUNSOFT_2:
935               if (state->m_mapper == 93)
936                  state->m_hard_mirroring = PPU_MIRROR_VERT;  // only hardwired mirroring makes different mappers 89 & 93
937               break;
938            case STD_BXROM:
939               if (state->m_crc_hack)
940                  state->m_pcb_id = AVE_NINA01;   // Mapper 34 is used for 2 diff boards
941               break;
942            case BANDAI_LZ93:
943               if (state->m_crc_hack)
944                  state->m_pcb_id = BANDAI_JUMP2; // Mapper 153 is used for 2 diff boards
945               break;
946            case IREM_HOLYDIV:
947               if (state->m_crc_hack)
948                  state->m_pcb_id = JALECO_JF16;  // Mapper 78 is used for 2 diff boards
949               break;
950            case CAMERICA_BF9093:
951               if (state->m_crc_hack)
952                  state->m_pcb_id = CAMERICA_BF9097;  // Mapper 71 is used for 2 diff boards
953               break;
954            case HES_BOARD:
955               if (state->m_crc_hack)
956                  state->m_pcb_id = HES6IN1_BOARD;    // Mapper 113 is used for 2 diff boards
957               break;
958            case WAIXING_ZS:
959               if (state->m_crc_hack)
960                  state->m_pcb_id = WAIXING_DQ8;  // Mapper 242 is used for 2 diff boards
961               break;
962            case BMC_GOLD_7IN1:
963               if (state->m_crc_hack)
964                  state->m_pcb_id = BMC_MARIOPARTY_7IN1;  // Mapper 52 is used for 2 diff boards
965               break;
966               //FIXME: we also have to fix Action 52 PRG loading somewhere...
967         }
968
969         /* Allocate internal Mapper RAM for boards which require it */
970         if (state->m_pcb_id == STD_EXROM)
971            state->m_mapper_ram = auto_alloc_array(image.device().machine(), UINT8, 0x400);
972
973         if (state->m_pcb_id == TAITO_X1_005 || state->m_pcb_id == TAITO_X1_005_A)
974            state->m_mapper_bram = auto_alloc_array(image.device().machine(), UINT8, 0x80);
975
976         if (state->m_pcb_id == TAITO_X1_017)
977            state->m_mapper_bram = auto_alloc_array(image.device().machine(), UINT8, 0x1400);
978
979         if (state->m_pcb_id == NAMCOT_163)
980            state->m_mapper_ram = auto_alloc_array(image.device().machine(), UINT8, 0x2000);
981
982         if (state->m_pcb_id == FUKUTAKE_BOARD)
983            state->m_mapper_ram = auto_alloc_array(image.device().machine(), UINT8, 2816);
984
985         /* Position past the header */
986         image.fseek(16, SEEK_SET);
987
988         /* Load the 0x200 byte trainer at 0x7000 if it exists */
989         if (state->m_trainer)
990            image.fread(&state->m_wram[0x1000], 0x200);
991
992         /* Read in the program chunks */
993         image.fread(&state->m_prg[0], 0x4000 * state->m_prg_chunks);
994         if (state->m_prg_chunks == 1)
995            memcpy(&state->m_prg[0x4000], &state->m_prg[0], 0x4000);
996
997#if SPLIT_PRG
998         {
999            FILE *prgout;
1000            char outname[255];
1001
1002            sprintf(outname, "%s.prg", image.filename());
1003            prgout = fopen(outname, "wb");
1004            if (prgout)
1005            {
1006               fwrite(&state->m_prg[0], 1, 0x4000 * state->m_prg_chunks, prgout);
1007               mame_printf_error("Created PRG chunk\n");
1008            }
1009
1010            fclose(prgout);
1011         }
1012#endif
1013
1014         logerror("**\n");
1015         logerror("Mapper: %d\n", state->m_mapper);
1016         logerror("PRG chunks: %02x, size: %06x\n", state->m_prg_chunks, 0x4000 * state->m_prg_chunks);
1017         // mame_printf_error("Mapper: %d\n", state->m_mapper);
1018         // mame_printf_error("PRG chunks: %02x, size: %06x\n", state->m_prg_chunks, 0x4000 * state->m_prg_chunks);
1019
1020         /* Read in any chr chunks */
1021         if (state->m_chr_chunks > 0)
1022         {
1023            image.fread(state->m_vrom, state->m_chr_chunks * 0x2000);
1024            if (state->m_mapper == 2)
1025               logerror("Warning: VROM has been found in VRAM-based mapper. Either the mapper is set wrong or the ROM image is incorrect.\n");
1026         }
1027
1028#if SPLIT_CHR
1029         if (state->m_chr_chunks > 0)
1030         {
1031            FILE *chrout;
1032            char outname[255];
1033
1034            sprintf(outname, "%s.chr", image.filename());
1035            chrout= fopen(outname, "wb");
1036            if (chrout)
1037            {
1038               fwrite(state->m_vrom, 1, 0x2000 * state->m_chr_chunks, chrout);
1039               mame_printf_error("Created CHR chunk\n");
1040            }
1041            fclose(chrout);
1042         }
1043#endif
1044
1045         logerror("CHR chunks: %02x, size: %06x\n", state->m_chr_chunks, 0x2000 * state->m_chr_chunks);
1046         logerror("**\n");
1047         // mame_printf_error("CHR chunks: %02x, size: %06x\n", state->m_chr_chunks, 0x2000 * state->m_chr_chunks);
1048         // mame_printf_error("**\n");
1049      }
1050      else if ((magic[0] == 'U') && (magic[1] == 'N') && (magic[2] == 'I') && (magic[3] == 'F')) /* If header starts with 'UNIF' it is UNIF */
1051      {
1052         UINT32 unif_ver = 0;
1053         char magic2[4];
1054         UINT8 buffer[4];
1055         UINT32 chunk_length = 0, read_length = 0x20;
1056         UINT32 prg_start = 0, chr_start = 0, prg_size;
1057         char unif_mapr[32]; // here we should store MAPR chunks
1058         UINT32 size = image.length();
1059         int mapr_chunk_found = 0;
1060         // allocate space to temporarily store PRG & CHR banks
1061         UINT8 *temp_prg = auto_alloc_array(image.device().machine(), UINT8, 256 * 0x4000);
1062         UINT8 *temp_chr = auto_alloc_array(image.device().machine(), UINT8, 256 * 0x2000);
1063         UINT8 temp_byte = 0;
1064
1065         /* init prg/chr chunks to 0: the exact number of chunks will be determined while reading the file */
1066         state->m_prg_chunks = 0;
1067         state->m_chr_chunks = 0;
1068
1069         image.fread(&buffer, 4);
1070         unif_ver = buffer[0] | (buffer[1] << 8) | (buffer[2] << 16) | (buffer[3] << 24);
1071         logerror("UNIF file found, version %d\n", unif_ver);
1072
1073         if (size <= 0x20)
1074         {
1075            logerror("%s only contains the UNIF header and no data.\n", image.filename());
1076            return IMAGE_INIT_FAIL;
1077         }
1078
1079         do
1080         {
1081            image.fseek(read_length, SEEK_SET);
1082
1083            memset(magic2, '\0', sizeof(magic2));
1084            image.fread(&magic2, 4);
1085
1086            /* We first run through the whole image to find a [MAPR] chunk. This is needed
1087             because, unfortunately, the MAPR chunk is not always the first chunk (see
1088             Super 24-in-1). When such a chunk is found, we set mapr_chunk_found=1 and
1089             we go back to load other chunks! */
1090            if (!mapr_chunk_found)
1091            {
1092               if ((magic2[0] == 'M') && (magic2[1] == 'A') && (magic2[2] == 'P') && (magic2[3] == 'R'))
1093               {
1094                  mapr_chunk_found = 1;
1095                  logerror("[MAPR] chunk found: ");
1096                  image.fread(&buffer, 4);
1097                  chunk_length = buffer[0] | (buffer[1] << 8) | (buffer[2] << 16) | (buffer[3] << 24);
1098
1099                  if (chunk_length <= 0x20)
1100                     image.fread(&unif_mapr, chunk_length);
1101
1102                  // find out prg/chr size, battery, wram, etc.
1103                  unif_mapr_setup(image.device().machine(), unif_mapr);
1104
1105                  /* now that we found the MAPR chunk, we can go back to load other chunks */
1106                  image.fseek(0x20, SEEK_SET);
1107                  read_length = 0x20;
1108               }
1109               else
1110               {
1111                  logerror("Skip this chunk. We need a [MAPR] chunk before anything else.\n");
1112                  image.fread(&buffer, 4);
1113                  chunk_length = buffer[0] | (buffer[1] << 8) | (buffer[2] << 16) | (buffer[3] << 24);
1114
1115                  read_length += (chunk_length + 8);
1116               }
1117            }
1118            else
1119            {
1120               /* What kind of chunk do we have here? */
1121               if ((magic2[0] == 'M') && (magic2[1] == 'A') && (magic2[2] == 'P') && (magic2[3] == 'R'))
1122               {
1123                  /* The [MAPR] chunk has already been read, so we skip it */
1124                  /* TO DO: it would be nice to check if more than one MAPR chunk is present */
1125                  logerror("[MAPR] chunk found (in the 2nd run). Already loaded.\n");
1126                  image.fread(&buffer, 4);
1127                  chunk_length = buffer[0] | (buffer[1] << 8) | (buffer[2] << 16) | (buffer[3] << 24);
1128
1129                  read_length += (chunk_length + 8);
1130               }
1131               else if ((magic2[0] == 'R') && (magic2[1] == 'E') && (magic2[2] == 'A') && (magic2[3] == 'D'))
1132               {
1133                  logerror("[READ] chunk found. No support yet.\n");
1134                  image.fread(&buffer, 4);
1135                  chunk_length = buffer[0] | (buffer[1] << 8) | (buffer[2] << 16) | (buffer[3] << 24);
1136
1137                  read_length += (chunk_length + 8);
1138               }
1139               else if ((magic2[0] == 'N') && (magic2[1] == 'A') && (magic2[2] == 'M') && (magic2[3] == 'E'))
1140               {
1141                  logerror("[NAME] chunk found. No support yet.\n");
1142                  image.fread(&buffer, 4);
1143                  chunk_length = buffer[0] | (buffer[1] << 8) | (buffer[2] << 16) | (buffer[3] << 24);
1144
1145                  read_length += (chunk_length + 8);
1146               }
1147               else if ((magic2[0] == 'W') && (magic2[1] == 'R') && (magic2[2] == 'T') && (magic2[3] == 'R'))
1148               {
1149                  logerror("[WRTR] chunk found. No support yet.\n");
1150                  image.fread(&buffer, 4);
1151                  chunk_length = buffer[0] | (buffer[1] << 8) | (buffer[2] << 16) | (buffer[3] << 24);
1152
1153                  read_length += (chunk_length + 8);
1154               }
1155               else if ((magic2[0] == 'T') && (magic2[1] == 'V') && (magic2[2] == 'C') && (magic2[3] == 'I'))
1156               {
1157                  logerror("[TVCI] chunk found.\n");
1158                  image.fread(&buffer, 4);
1159                  chunk_length = buffer[0] | (buffer[1] << 8) | (buffer[2] << 16) | (buffer[3] << 24);
1160
1161                  image.fread(&temp_byte, 1);
1162                  logerror("Television Standard : %s\n", (temp_byte == 0) ? "NTSC" : (temp_byte == 1) ? "PAL" : "Does not matter");
1163
1164                  read_length += (chunk_length + 8);
1165               }
1166               else if ((magic2[0] == 'T') && (magic2[1] == 'V') && (magic2[2] == 'S') && (magic2[3] == 'C')) // is this the same as TVCI??
1167               {
1168                  logerror("[TVSC] chunk found. No support yet.\n");
1169                  image.fread(&buffer, 4);
1170                  chunk_length = buffer[0] | (buffer[1] << 8) | (buffer[2] << 16) | (buffer[3] << 24);
1171
1172                  read_length += (chunk_length + 8);
1173               }
1174               else if ((magic2[0] == 'D') && (magic2[1] == 'I') && (magic2[2] == 'N') && (magic2[3] == 'F'))
1175               {
1176                  logerror("[DINF] chunk found. No support yet.\n");
1177                  image.fread(&buffer, 4);
1178                  chunk_length = buffer[0] | (buffer[1] << 8) | (buffer[2] << 16) | (buffer[3] << 24);
1179
1180                  read_length += (chunk_length + 8);
1181               }
1182               else if ((magic2[0] == 'C') && (magic2[1] == 'T') && (magic2[2] == 'R') && (magic2[3] == 'L'))
1183               {
1184                  logerror("[CTRL] chunk found. No support yet.\n");
1185                  image.fread(&buffer, 4);
1186                  chunk_length = buffer[0] | (buffer[1] << 8) | (buffer[2] << 16) | (buffer[3] << 24);
1187
1188                  read_length += (chunk_length + 8);
1189               }
1190               else if ((magic2[0] == 'B') && (magic2[1] == 'A') && (magic2[2] == 'T') && (magic2[3] == 'R'))
1191               {
1192                  logerror("[BATR] chunk found. No support yet.\n");
1193                  image.fread(&buffer, 4);
1194                  chunk_length = buffer[0] | (buffer[1] << 8) | (buffer[2] << 16) | (buffer[3] << 24);
1195
1196                  read_length += (chunk_length + 8);
1197               }
1198               else if ((magic2[0] == 'V') && (magic2[1] == 'R') && (magic2[2] == 'O') && (magic2[3] == 'R'))
1199               {
1200                  logerror("[VROR] chunk found. No support yet.\n");
1201                  image.fread(&buffer, 4);
1202                  chunk_length = buffer[0] | (buffer[1] << 8) | (buffer[2] << 16) | (buffer[3] << 24);
1203
1204                  read_length += (chunk_length + 8);
1205               }
1206               else if ((magic2[0] == 'M') && (magic2[1] == 'I') && (magic2[2] == 'R') && (magic2[3] == 'R'))
1207               {
1208                  logerror("[MIRR] chunk found.\n");
1209                  image.fread(&buffer, 4);
1210                  chunk_length = buffer[0] | (buffer[1] << 8) | (buffer[2] << 16) | (buffer[3] << 24);
1211
1212                  image.fread(&temp_byte, 1);
1213                  switch (temp_byte)
1214                  {
1215                     case 0: // Horizontal Mirroring (Hard Wired)
1216                        state->m_hard_mirroring = PPU_MIRROR_HORZ;
1217                        break;
1218                     case 1: // Vertical Mirroring (Hard Wired)
1219                        state->m_hard_mirroring = PPU_MIRROR_VERT;
1220                        break;
1221                     case 2: // Mirror All Pages From $2000 (Hard Wired)
1222                        state->m_hard_mirroring = PPU_MIRROR_LOW;
1223                        break;
1224                     case 3: // Mirror All Pages From $2400 (Hard Wired)
1225                        state->m_hard_mirroring = PPU_MIRROR_HIGH;
1226                        break;
1227                     case 4: // Four Screens of VRAM (Hard Wired)
1228                        state->m_four_screen_vram = 1;
1229                        break;
1230                     case 5: // Mirroring Controlled By Mapper Hardware
1231                        logerror("Mirroring handled by the board hardware.\n");
1232                        // default to horizontal at start
1233                        state->m_hard_mirroring = PPU_MIRROR_HORZ;
1234                        break;
1235                     default:
1236                        logerror("Undocumented mirroring value.\n");
1237                        // default to horizontal
1238                        state->m_hard_mirroring = PPU_MIRROR_HORZ;
1239                        break;
1240                  }
1241
1242                  read_length += (chunk_length + 8);
1243               }
1244               else if ((magic2[0] == 'P') && (magic2[1] == 'C') && (magic2[2] == 'K'))
1245               {
1246                  logerror("[PCK%c] chunk found. No support yet.\n", magic2[3]);
1247                  image.fread(&buffer, 4);
1248                  chunk_length = buffer[0] | (buffer[1] << 8) | (buffer[2] << 16) | (buffer[3] << 24);
1249
1250                  read_length += (chunk_length + 8);
1251               }
1252               else if ((magic2[0] == 'C') && (magic2[1] == 'C') && (magic2[2] == 'K'))
1253               {
1254                  logerror("[CCK%c] chunk found. No support yet.\n", magic2[3]);
1255                  image.fread(&buffer, 4);
1256                  chunk_length = buffer[0] | (buffer[1] << 8) | (buffer[2] << 16) | (buffer[3] << 24);
1257
1258                  read_length += (chunk_length + 8);
1259               }
1260               else if ((magic2[0] == 'P') && (magic2[1] == 'R') && (magic2[2] == 'G'))
1261               {
1262                  logerror("[PRG%c] chunk found. ", magic2[3]);
1263                  image.fread(&buffer, 4);
1264                  chunk_length = buffer[0] | (buffer[1] << 8) | (buffer[2] << 16) | (buffer[3] << 24);
1265
1266                  // FIXME: we currently don't support PRG chunks smaller than 16K!
1267                  state->m_prg_chunks += (chunk_length / 0x4000);
1268
1269                  if (chunk_length / 0x4000)
1270                     logerror("It consists of %d 16K-blocks.\n", chunk_length / 0x4000);
1271                  else
1272                     logerror("This chunk is smaller than 16K: the emulation might have issues. Please report this file to the MESS forums.\n");
1273
1274                  /* Read in the program chunks */
1275                  image.fread(&temp_prg[prg_start], chunk_length);
1276
1277                  prg_start += chunk_length;
1278                  read_length += (chunk_length + 8);
1279               }
1280               else if ((magic2[0] == 'C') && (magic2[1] == 'H') && (magic2[2] == 'R'))
1281               {
1282                  logerror("[CHR%c] chunk found. ", magic2[3]);
1283                  image.fread(&buffer, 4);
1284                  chunk_length = buffer[0] | (buffer[1] << 8) | (buffer[2] << 16) | (buffer[3] << 24);
1285
1286                  state->m_chr_chunks += (chunk_length / 0x2000);
1287
1288                  logerror("It consists of %d 8K-blocks.\n", chunk_length / 0x2000);
1289
1290                  /* Read in the vrom chunks */
1291                  image.fread(&temp_chr[chr_start], chunk_length);
1292
1293                  chr_start += chunk_length;
1294                  read_length += (chunk_length + 8);
1295               }
1296               else
1297               {
1298                  logerror("Unsupported UNIF chunk or corrupted header. Please report the problem at MESS Board.\n");
1299                  read_length = size;
1300               }
1301            }
1302         } while (size > read_length);
1303
1304         if (!mapr_chunk_found)
1305         {
1306            auto_free(image.device().machine(), temp_prg);
1307            auto_free(image.device().machine(), temp_chr);
1308            fatalerror("UNIF should have a [MAPR] chunk to work. Check if your image has been corrupted\n");
1309         }
1310
1311         if (!prg_start)
1312         {
1313            auto_free(image.device().machine(), temp_prg);
1314            auto_free(image.device().machine(), temp_chr);
1315            fatalerror("Unsupported UNIF chunk or corrupted header. Please report the problem at MESS Board.\n");
1316         }
1317
1318         // Allocate class pointers for PRG/VROM/VRAM/WRAM and copy data there from the temp copies
1319
1320         /* Take care of PRG */
1321         prg_size = (state->m_prg_chunks == 1) ? 2 * 0x4000 : state->m_prg_chunks * 0x4000;
1322         state->m_prg = auto_alloc_array(image.device().machine(), UINT8, prg_size);
1323
1324         memcpy(&state->m_prg[0], &temp_prg[0], state->m_prg_chunks * 0x4000);
1325         /* If only a single 16K PRG chunk is present, mirror it! */
1326         if (state->m_prg_chunks == 1)
1327            memcpy(&state->m_prg[0x4000], &state->m_prg[0], 0x4000);
1328
1329         /* Take care of CHR ROM */
1330         if (state->m_chr_chunks)
1331         {
1332            state->m_vrom = auto_alloc_array(image.device().machine(), UINT8, state->m_chr_chunks * 0x2000);
1333            memcpy(&state->m_vrom[0x00000], &temp_chr[0x00000], state->m_chr_chunks * 0x2000);
1334         }
1335
1336         /* Take care of CHR RAM */
1337         if (state->m_vram_chunks)
1338            state->m_vram = auto_alloc_array(image.device().machine(), UINT8, state->m_vram_chunks * 0x2000);
1339
1340         // FIXME: this should only be allocated if there is actual wram in the cart (i.e. if state->m_prg_ram = 1)!
1341         state->m_wram_size = 0x10000;
1342         state->m_wram = auto_alloc_array(image.device().machine(), UINT8, state->m_wram_size);
1343
1344#if SPLIT_PRG
1345         {
1346            FILE *prgout;
1347            char outname[255];
1348
1349            sprintf(outname, "%s.prg", image.filename());
1350            prgout = fopen(outname, "wb");
1351            if (prgout)
1352            {
1353               fwrite(&state->m_prg[0], 1, 0x4000 * state->m_prg_chunks, prgout);
1354               mame_printf_error("Created PRG chunk\n");
1355            }
1356
1357            fclose(prgout);
1358         }
1359#endif
1360
1361#if SPLIT_CHR
1362         if (state->m_chr_chunks > 0)
1363         {
1364            FILE *chrout;
1365            char outname[255];
1366
1367            sprintf(outname, "%s.chr", image.filename());
1368            chrout= fopen(outname, "wb");
1369            if (chrout)
1370            {
1371               fwrite(state->m_vrom, 1, 0x2000 * state->m_chr_chunks, chrout);
1372               mame_printf_error("Created CHR chunk\n");
1373            }
1374            fclose(chrout);
1375         }
1376#endif
1377         // free the temporary copy of PRG/CHR
1378         auto_free(image.device().machine(), temp_prg);
1379         auto_free(image.device().machine(), temp_chr);
1380         logerror("UNIF support is only very preliminary.\n");
1381      }
1382      else
1383      {
1384         logerror("%s is NOT a file in either iNES or UNIF format.\n", image.filename());
1385         return IMAGE_INIT_FAIL;
1386      }
1387   }
1388   else
1389   {
1390      UINT32 prg_size = image.get_software_region_length("prg");
1391      UINT32 chr_size = image.get_software_region_length("chr");
1392      UINT32 vram_size = image.get_software_region_length("vram");
1393      vram_size += image.get_software_region_length("vram2");
1394
1395      // validate the xml fields
1396      if (!prg_size)
1397         fatalerror("No PRG entry for this software! Please check if the xml list got corrupted\n");
1398      if (prg_size < 0x8000)
1399         fatalerror("PRG entry is too small! Please check if the xml list got corrupted\n");
1400
1401      // Allocate class pointers for PRG/VROM/VRAM/WRAM and copy data there from the temp copies
1402      state->m_prg = auto_alloc_array(image.device().machine(), UINT8, prg_size);
1403
1404      if (chr_size)
1405         state->m_vrom = auto_alloc_array(image.device().machine(), UINT8, chr_size);
1406
1407      if (vram_size)
1408         state->m_vram = auto_alloc_array(image.device().machine(), UINT8, vram_size);
1409
1410      memcpy(state->m_prg, image.get_software_region("prg"), prg_size);
1411
1412      if (chr_size)
1413         memcpy(state->m_vrom, image.get_software_region("chr"), chr_size);
1414
1415      state->m_prg_chunks = prg_size / 0x4000;
1416      state->m_chr_chunks = chr_size / 0x2000;
1417      state->m_vram_chunks = vram_size / 0x2000;
1418
1419      state->m_pcb_id = nes_get_pcb_id(image.device().machine(), image.get_feature("pcb"));
1420
1421      if (state->m_pcb_id == STD_TVROM || state->m_pcb_id == STD_DRROM || state->m_pcb_id == IREM_LROG017)
1422         state->m_four_screen_vram = 1;
1423      else
1424         state->m_four_screen_vram = 0;
1425
1426      state->m_battery = (image.get_software_region("bwram") != NULL) ? 1 : 0;
1427      state->m_battery_size = image.get_software_region_length("bwram");
1428
1429      if (state->m_pcb_id == BANDAI_LZ93EX)
1430      {
1431         // allocate the 24C01 or 24C02 EEPROM
1432         state->m_battery = 1;
1433         state->m_battery_size += 0x2000;
1434      }
1435
1436      if (state->m_pcb_id == BANDAI_DATACH)
1437      {
1438         // allocate the 24C01 and 24C02 EEPROM
1439         state->m_battery = 1;
1440         state->m_battery_size += 0x4000;
1441      }
1442
1443      state->m_prg_ram = (image.get_software_region("wram") != NULL) ? 1 : 0;
1444      state->m_wram_size = image.get_software_region_length("wram");
1445      state->m_mapper_ram_size = image.get_software_region_length("mapper_ram");
1446      state->m_mapper_bram_size = image.get_software_region_length("mapper_bram");
1447
1448      if (state->m_prg_ram)
1449         state->m_wram = auto_alloc_array(image.device().machine(), UINT8, state->m_wram_size);
1450      if (state->m_mapper_ram_size)
1451         state->m_mapper_ram = auto_alloc_array(image.device().machine(), UINT8, state->m_mapper_ram_size);
1452      if (state->m_mapper_bram_size)
1453         state->m_mapper_bram = auto_alloc_array(image.device().machine(), UINT8, state->m_mapper_bram_size);
1454
1455      /* Check for mirroring */
1456      if (image.get_feature("mirroring") != NULL)
1457      {
1458         const char *mirroring = image.get_feature("mirroring");
1459         if (!strcmp(mirroring, "horizontal"))
1460            state->m_hard_mirroring = PPU_MIRROR_HORZ;
1461         if (!strcmp(mirroring, "vertical"))
1462            state->m_hard_mirroring = PPU_MIRROR_VERT;
1463         if (!strcmp(mirroring, "high"))
1464            state->m_hard_mirroring = PPU_MIRROR_HIGH;
1465         if (!strcmp(mirroring, "low"))
1466            state->m_hard_mirroring = PPU_MIRROR_LOW;
1467      }
1468
1469      state->m_chr_open_bus = 0;
1470      state->m_ce_mask = 0;
1471      state->m_ce_state = 0;
1472      state->m_vrc_ls_prg_a = 0;
1473      state->m_vrc_ls_prg_b = 0;
1474      state->m_vrc_ls_chr = 0;
1475
1476      /* Check for pins in specific boards which require them */
1477      if (state->m_pcb_id == STD_CNROM)
1478      {
1479         if (image.get_feature("chr-pin26") != NULL)
1480         {
1481            state->m_ce_mask |= 0x01;
1482            state->m_ce_state |= !strcmp(image.get_feature("chr-pin26"), "CE") ? 0x01 : 0;
1483         }
1484         if (image.get_feature("chr-pin27") != NULL)
1485         {
1486            state->m_ce_mask |= 0x02;
1487            state->m_ce_state |= !strcmp(image.get_feature("chr-pin27"), "CE") ? 0x02 : 0;
1488         }
1489      }
1490
1491      if (state->m_pcb_id == TAITO_X1_005 && image.get_feature("x1-pin17") != NULL && image.get_feature("x1-pin31") != NULL)
1492      {
1493         if (!strcmp(image.get_feature("x1-pin17"), "CIRAM A10") && !strcmp(image.get_feature("x1-pin31"), "NC"))
1494            state->m_pcb_id = TAITO_X1_005_A;
1495      }
1496
1497      if (state->m_pcb_id == KONAMI_VRC2)
1498      {
1499         state->m_vrc_ls_prg_a = nes_cart_get_line(image.get_feature("vrc2-pin3"));
1500         state->m_vrc_ls_prg_b = nes_cart_get_line(image.get_feature("vrc2-pin4"));
1501         state->m_vrc_ls_chr = (nes_cart_get_line(image.get_feature("vrc2-pin21")) != 10) ? 1 : 0;
1502//          mame_printf_error("VRC-2, pin3: A%d, pin4: A%d, pin21: %s\n", state->m_vrc_ls_prg_a, state->m_vrc_ls_prg_b, state->m_vrc_ls_chr ? "NC" : "A10");
1503      }
1504
1505      if (state->m_pcb_id == KONAMI_VRC4)
1506      {
1507         state->m_vrc_ls_prg_a = nes_cart_get_line(image.get_feature("vrc4-pin3"));
1508         state->m_vrc_ls_prg_b = nes_cart_get_line(image.get_feature("vrc4-pin4"));
1509//          mame_printf_error("VRC-4, pin3: A%d, pin4: A%d\n", state->m_vrc_ls_prg_a, state->m_vrc_ls_prg_b);
1510      }
1511
1512      if (state->m_pcb_id == KONAMI_VRC6)
1513      {
1514         state->m_vrc_ls_prg_a = nes_cart_get_line(image.get_feature("vrc6-pin9"));
1515         state->m_vrc_ls_prg_b = nes_cart_get_line(image.get_feature("vrc6-pin10"));
1516//          mame_printf_error("VRC-6, pin9: A%d, pin10: A%d\n", state->m_vrc_ls_prg_a, state->m_vrc_ls_prg_b);
1517      }
1518
1519      /* Check for other misc board variants */
1520      if (state->m_pcb_id == STD_SOROM)
1521      {
1522         if (image.get_feature("mmc1_type") != NULL && !strcmp(image.get_feature("mmc1_type"), "MMC1A"))
1523            state->m_pcb_id = STD_SOROM_A;  // in MMC1-A PRG RAM is always enabled
1524      }
1525
1526      if (state->m_pcb_id == STD_SXROM)
1527      {
1528         if (image.get_feature("mmc1_type") != NULL && !strcmp(image.get_feature("mmc1_type"), "MMC1A"))
1529            state->m_pcb_id = STD_SXROM_A;  // in MMC1-A PRG RAM is always enabled
1530      }
1531
1532      if (state->m_pcb_id == STD_NXROM || state->m_pcb_id == SUNSOFT_DCS)
1533      {
1534         if (image.get_software_region("minicart") != NULL)  // check for dual minicart
1535         {
1536            state->m_pcb_id = SUNSOFT_DCS;
1537            // we shall load somewhere the minicart, but we still do not support this
1538         }
1539      }
1540
1541#if 0
1542      if (state->m_pcb_id == UNSUPPORTED_BOARD)
1543         mame_printf_error("This board (%s) is currently not supported by MESS\n", image.get_feature("pcb"));
1544      mame_printf_error("PCB Feature: %s\n", image.get_feature("pcb"));
1545      mame_printf_error("PRG chunks: %d\n", state->m_prg_chunks);
1546      mame_printf_error("CHR chunks: %d\n", state->m_chr_chunks);
1547      mame_printf_error("VRAM: Present %s, size: %d\n", state->m_vram_chunks ? "Yes" : "No", vram_size);
1548      mame_printf_error("NVWRAM: Present %s, size: %d\n", state->m_battery ? "Yes" : "No", state->m_battery_size);
1549      mame_printf_error("WRAM:   Present %s, size: %d\n", state->m_prg_ram ? "Yes" : "No", state->m_wram_size);
1550#endif
1551   }
1552
1553   // Attempt to load a battery file for this ROM
1554   // A few boards have internal RAM with a battery (MMC6, Taito X1-005 & X1-017, etc.)
1555   if (state->m_battery || state->m_mapper_bram_size)
1556   {
1557      UINT8 *temp_nvram = auto_alloc_array(image.device().machine(), UINT8, state->m_battery_size + state->m_mapper_bram_size);
1558      image.battery_load(temp_nvram, state->m_battery_size + state->m_mapper_bram_size, 0x00);
1559      if (state->m_battery)
1560      {
1561         state->m_battery_ram = auto_alloc_array(image.device().machine(), UINT8, state->m_battery_size);
1562         memcpy(state->m_battery_ram, temp_nvram, state->m_battery_size);
1563      }
1564      if (state->m_mapper_bram_size)
1565         memcpy(state->m_mapper_bram, temp_nvram + state->m_battery_size, state->m_mapper_bram_size);
1566
1567      auto_free(image.device().machine(), temp_nvram);
1568   }
1569
1570   return IMAGE_INIT_PASS;
1571}
1572
1573
1574
1575712void nes_partialhash(hash_collection &dest, const unsigned char *data,
1576713   unsigned long length, const char *functions)
1577714{
trunk/src/mess/machine/nes_slot.c
r0r20931
1#include "emu.h"
2#include "machine/nes_slot.h"
3
4
5#define NES_BATTERY_SIZE 0x2000
6
7//**************************************************************************
8//  GLOBAL VARIABLES
9//**************************************************************************
10
11const device_type NES_CART_SLOT = &device_creator<nes_cart_slot_device>;
12const device_type FC_CART_SLOT = &device_creator<fc_cart_slot_device>;
13
14
15//**************************************************************************
16//    NES cartridges Interface
17//**************************************************************************
18
19//-------------------------------------------------
20//  device_nes_cart_interface - constructor
21//-------------------------------------------------
22
23device_nes_cart_interface::device_nes_cart_interface(const machine_config &mconfig, device_t &device)
24                  : device_slot_card_interface(mconfig, device),
25                  m_prg(NULL),
26                  m_prgram(NULL),
27                  m_vrom(NULL),
28                  m_vram(NULL),
29                  m_battery(NULL),
30                  m_mapper_ram(NULL),
31                  m_mapper_bram(NULL),
32                  m_prg_size(0),
33                  m_prgram_size(0),
34                  m_vrom_size(0),
35                  m_vram_size(0),
36                  m_battery_size(0),
37                  m_mapper_ram_size(0),
38                  m_mapper_bram_size(0)
39{
40}
41
42
43//-------------------------------------------------
44//  ~device_nes_cart_interface - destructor
45//-------------------------------------------------
46
47device_nes_cart_interface::~device_nes_cart_interface()
48{
49}
50
51//-------------------------------------------------
52//  pointer allocators
53//-------------------------------------------------
54
55void device_nes_cart_interface::prg_alloc(running_machine &machine, size_t size)
56{
57   if (m_prg == NULL)
58   {
59      m_prg = auto_alloc_array(machine, UINT8, size);
60      m_prg_size = size;
61   }
62}
63
64void device_nes_cart_interface::prgram_alloc(running_machine &machine, size_t size)
65{
66   if (m_prgram == NULL)
67   {
68      m_prgram = auto_alloc_array(machine, UINT8, size);
69      m_prgram_size = size;
70   }
71}
72
73void device_nes_cart_interface::vrom_alloc(running_machine &machine, size_t size)
74{
75   if (m_vrom == NULL)
76   {
77      m_vrom = auto_alloc_array(machine, UINT8, size);
78      m_vrom_size = size;
79   }
80}
81
82void device_nes_cart_interface::vram_alloc(running_machine &machine, size_t size)
83{
84   if (m_vram == NULL)
85   {
86      m_vram = auto_alloc_array(machine, UINT8, size);
87      m_vram_size = size;
88   }
89}
90
91void device_nes_cart_interface::battery_alloc(running_machine &machine, size_t size)
92{
93   if (m_battery == NULL)
94   {
95      m_battery = auto_alloc_array(machine, UINT8, size);
96      m_battery_size = size;
97   }
98}
99
100void device_nes_cart_interface::mapper_ram_alloc(running_machine &machine, size_t size)
101{
102   if (m_mapper_ram == NULL)
103   {
104      m_mapper_ram = auto_alloc_array(machine, UINT8, size);
105      m_mapper_ram_size = size;
106   }
107}
108
109void device_nes_cart_interface::mapper_bram_alloc(running_machine &machine, size_t size)
110{
111   if (m_mapper_bram == NULL)
112   {
113      m_mapper_bram = auto_alloc_array(machine, UINT8, size);
114      m_mapper_bram_size = size;
115   }
116}
117
118
119//**************************************************************************
120//  LIVE DEVICE
121//**************************************************************************
122
123//-------------------------------------------------
124//  base_nes_cart_slot_device - constructor
125//-------------------------------------------------
126base_nes_cart_slot_device::base_nes_cart_slot_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock) :
127                  device_t(mconfig, type, name, tag, owner, clock),
128                  device_image_interface(mconfig, *this),
129                  device_slot_interface(mconfig, *this),
130                  m_chr_open_bus(0),
131                  m_ce_mask(0),
132                  m_ce_state(0),
133                  m_vrc_ls_prg_a(0),
134                  m_vrc_ls_prg_b(0),
135                  m_vrc_ls_chr(0),
136                  m_crc_hack(0)
137{
138}
139
140nes_cart_slot_device::nes_cart_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
141                  base_nes_cart_slot_device(mconfig, NES_CART_SLOT, "NES Cartridge Slot", tag, owner, clock)
142{
143}
144
145fc_cart_slot_device::fc_cart_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
146                  base_nes_cart_slot_device(mconfig, FC_CART_SLOT, "FC Cartridge Slot", tag, owner, clock)
147{
148}
149
150//-------------------------------------------------
151//  base_nes_cart_slot_device - destructor
152//-------------------------------------------------
153
154base_nes_cart_slot_device::~base_nes_cart_slot_device()
155{
156}
157
158//-------------------------------------------------
159//  device_start - device-specific startup
160//-------------------------------------------------
161
162void base_nes_cart_slot_device::device_start()
163{
164   m_cart = dynamic_cast<device_nes_cart_interface *>(get_card_device());
165}
166
167//-------------------------------------------------
168//  device_config_complete - perform any
169//  operations now that the configuration is
170//  complete
171//-------------------------------------------------
172
173void base_nes_cart_slot_device::device_config_complete()
174{
175   // inherit a copy of the static data
176//   const nes_cart_interface *intf = reinterpret_cast<const nes_cart_interface *>(static_config());
177//   if (intf != NULL)
178//   {
179//      *static_cast<nes_cart_interface *>(this) = *intf;
180//   }
181   
182   // set brief and instance name
183   update_names();
184}
185
186
187//-------------------------------------------------
188//  device_timer - handler timer events
189//-------------------------------------------------
190
191/*-------------------------------------------------
192 call load
193 -------------------------------------------------*/
194
195
196struct nes_cart_lines
197{
198   const char *tag;
199   int line;
200};
201
202static const struct nes_cart_lines nes_cart_lines_table[] =
203{
204   { "PRG A0",    0 },
205   { "PRG A1",    1 },
206   { "PRG A2",    2 },
207   { "PRG A3",    3 },
208   { "PRG A4",    4 },
209   { "PRG A5",    5 },
210   { "PRG A6",    6 },
211   { "PRG A7",    7 },
212   { "CHR A10",  10 },
213   { "CHR A11",  11 },
214   { "CHR A12",  12 },
215   { "CHR A13",  13 },
216   { "CHR A14",  14 },
217   { "CHR A15",  15 },
218   { "CHR A16",  16 },
219   { "CHR A17",  17 },
220   { "NC",      127 },
221   { 0 }
222};
223
224static int nes_cart_get_line( const char *feature )
225{
226   const struct nes_cart_lines *nes_line = &nes_cart_lines_table[0];
227   
228   if (feature == NULL)
229      return 128;
230   
231   while (nes_line->tag)
232   {
233      if (strcmp(nes_line->tag, feature) == 0)
234         break;
235     
236      nes_line++;
237   }
238   
239   return nes_line->line;
240}
241
242/* Set to generate prg & chr files when the cart is loaded */
243#define SPLIT_PRG   0
244#define SPLIT_CHR   0
245
246bool base_nes_cart_slot_device::call_load()
247{
248   if (m_cart)
249   {
250      UINT32 vram_size = 0, prgram_size = 0, battery_size = 0, mapper_ram_size = 0, mapper_bram_size = 0;   // helper for regions to alloc at the end
251
252      if (software_entry() == NULL)
253      {
254         const char *mapinfo = NULL;
255         int mapint1 = 0, mapint2 = 0, mapint3 = 0, mapint4 = 0;
256         char magic[4];
257         
258         /* Check first 4 bytes of the image to decide if it is UNIF or iNES */
259         /* Unfortunately, many .unf files have been released as .nes, so we cannot rely on extensions only */
260         memset(magic, '\0', sizeof(magic));
261         fread(magic, 4);
262         
263         if ((magic[0] == 'N') && (magic[1] == 'E') && (magic[2] == 'S'))    /* If header starts with 'NES' it is iNES */
264         {
265            UINT32 prg_size, vrom_size;
266            UINT8 header[0x10];
267            UINT8 mapper, local_options;
268            bool ines20 = FALSE, has_trainer = FALSE, prg16k;
269           
270            // check if the image is recognized by nes.hsi
271//              mapinfo = hashfile_extrainfo(image);
272           
273            // image_extrainfo() resets the file position back to start.
274            fseek(0, SEEK_SET);
275            // read out the header
276            fread(&header, 0x10);
277           
278            // SETUP step 1: getting PRG, VROM, VRAM sizes
279            prg16k = (header[4] == 1);
280            prg_size = prg16k ? 2 * 0x4000 : header[4] * 0x4000;
281            vrom_size = header[5] * 0x2000;
282            vram_size = 0x4000;
283           
284            // SETUP step 2: getting PCB and other settings
285            mapper = (header[6] & 0xf0) >> 4;
286            local_options = header[6] & 0x0f;
287           
288            switch (header[7] & 0xc)
289            {
290               case 0x4:
291               case 0xc:
292                  // probably the header got corrupted: don't trust upper bits for mapper
293                  break;
294                 
295               case 0x8:   // it's iNES 2.0 format
296                  ines20 = TRUE;
297               case 0x0:
298               default:
299                  mapper |= header[7] & 0xf0;
300                  break;
301            }
302           
303            // use info from nes.hsi if available!
304            if (mapinfo)
305            {
306               if (4 == sscanf(mapinfo,"%d %d %d %d", &mapint1, &mapint2, &mapint3, &mapint4))
307               {
308                  /* image is present in nes.hsi: overwrite the header settings with these */
309                  mapper = mapint1;
310                  local_options = mapint2 & 0x0f;
311                  m_crc_hack = (mapint2 & 0xf0) >> 4; // this is used to differentiate among variants of the same Mapper (see below)
312                  prg_size = mapint3 * 0x4000;
313                  vrom_size = mapint4 * 0x2000;
314                  logerror("NES.HSI info: %d %d %d %d\n", mapint1, mapint2, mapint3, mapint4);
315//                  mame_printf_error("NES.HSI info: %d %d %d %d\n", mapint1, mapint2, mapint3, mapint4);
316               }
317               else
318               {
319                  logerror("NES: [%s], Invalid mapinfo found\n", mapinfo);
320               }
321            }
322            else
323            {
324               logerror("NES: No extrainfo found\n");
325            }
326           
327            // use extended iNES2.0 info if available!
328            if (ines20)
329            {
330               mapper |= (header[8] & 0x0f) << 8;
331               // header[8] & 0xf0 is used for submappers, but I haven't found any specific image to implement this
332               prg_size += ((header[9] & 0x0f) << 8) * 0x4000;
333               vrom_size += ((header[9] & 0xf0) << 4) * 0x2000;
334            }
335           
336            // SETUP step 3: storing the info needed for emulation
337            m_pcb_id = nes_get_mmc_id(machine(), mapper);
338            m_cart->set_mirroring(BIT(local_options, 0) ? PPU_MIRROR_VERT : PPU_MIRROR_HORZ);
339            if (BIT(local_options, 1))
340               battery_size = NES_BATTERY_SIZE; // with original iNES format we can only support 8K WRAM battery
341            has_trainer = BIT(local_options, 2) ? TRUE : FALSE;
342            m_cart->set_four_screen_vram(BIT(local_options, 3));
343           
344            if (ines20)
345            {
346               // PRGRAM/BWRAM (not fully supported, also due to lack of 2.0 files)
347               if ((header[10] & 0x0f) > 0)
348                  prgram_size = 0x80 << ((header[10] & 0x0f) - 1);
349               if ((header[10] & 0xf0) > 0)
350                  battery_size = 0x80 << ((header[10] & 0xf0) - 5);
351               // VRAM
352               vram_size = 0;
353               if ((header[11] & 0x0f) > 0)
354                  vram_size = 0x80 << ((header[11] & 0x0f) - 1);
355               // header[11] & 0xf0 is the size of battery backed VRAM, found so far in Racermate II only and not supported yet
356            }
357            else
358            {
359               // always map PRGRAM/WRAM in bank5 (eventually, this should be enabled only for some mappers)
360               // and save it depending on has_battery
361
362               // PRGRAM size is 8k for most games, but pirate carts often use different sizes,
363               // so its size has been added recently to the iNES format spec, but almost no image uses it
364               prgram_size = header[8] ? header[8] * 0x2000 : 0x2000;
365            }
366           
367            // a few mappers correspond to multiple PCBs, so we need a few additional checks and tweaks
368            switch (m_pcb_id)
369            {
370               case STD_CNROM:
371                  if (mapper == 185)
372                  {
373                     switch (m_crc_hack)
374                     {
375                        case 0x0: // pin26: CE, pin27: CE (B-Wings, Bird Week)
376                           m_ce_mask = 0x03;
377                           m_ce_state = 0x03;
378                           break;
379                        case 0x4: // pin26: CE, pin27: /CE (Mighty Bomb Jack, Spy Vs. Spy)
380                           m_ce_mask = 0x03;
381                           m_ce_state = 0x01;
382                           break;
383                        case 0x8: // pin26: /CE, pin27: CE (Sansu 1, 2, 3 Nen)
384                           m_ce_mask = 0x03;
385                           m_ce_state = 0x02;
386                           break;
387                        case 0xc: // pin26: /CE, pin27: /CE (Seicross v2.0)
388                           m_ce_mask = 0x03;
389                           m_ce_state = 0x00;
390                           break;
391                     }
392                  }
393                  break;
394               case KONAMI_VRC2:
395                  if (mapper == 22)
396                  {
397                     m_vrc_ls_prg_a = 0;
398                     m_vrc_ls_prg_b = 1;
399                     m_vrc_ls_chr = 1;
400                  }
401                  if (mapper == 23 && !m_crc_hack)
402                  {
403                     m_vrc_ls_prg_a = 1;
404                     m_vrc_ls_prg_b = 0;
405                     m_vrc_ls_chr = 0;
406                  }
407                  if (mapper == 23 && m_crc_hack)
408                  {
409                     // here there are also Akumajou Special, Crisis Force, Parodius da!, Tiny Toons which are VRC-4
410                     m_vrc_ls_prg_a = 3;
411                     m_vrc_ls_prg_b = 2;
412                     m_pcb_id = KONAMI_VRC4; // this allows for konami_irq to be installed at reset
413                  }
414                  break;
415               case KONAMI_VRC4:
416                  if (mapper == 21)
417                  {
418                     // Wai Wai World 2 & Ganbare Goemon Gaiden 2 (the latter with crc_hack)
419                     m_vrc_ls_prg_a = m_crc_hack ? 7 : 2;
420                     m_vrc_ls_prg_b = m_crc_hack ? 6 : 1;
421                  }
422                  if (mapper == 25)   // here there is also Ganbare Goemon Gaiden which is VRC-2
423                  {
424                     m_vrc_ls_prg_a = m_crc_hack ? 2 : 0;
425                     m_vrc_ls_prg_b = m_crc_hack ? 3 : 1;
426                  }
427                  break;
428               case KONAMI_VRC6:
429                  if (mapper == 24)
430                  {
431                     m_vrc_ls_prg_a = 1;
432                     m_vrc_ls_prg_b = 0;
433                  }
434                  if (mapper == 26)
435                  {
436                     m_vrc_ls_prg_a = 0;
437                     m_vrc_ls_prg_b = 1;
438                  }
439                  break;
440               case IREM_G101:
441                  if (m_crc_hack)
442                     m_cart->set_mirroring(PPU_MIRROR_HIGH); // Major League has hardwired mirroring
443                  break;
444               case DIS_74X161X161X32:
445                  if (mapper == 70)
446                     m_cart->set_mirroring(PPU_MIRROR_VERT); // only hardwired mirroring makes different mappers 70 & 152
447                  break;
448               case SUNSOFT_2:
449                  if (mapper == 93)
450                     m_cart->set_mirroring(PPU_MIRROR_VERT); // only hardwired mirroring makes different mappers 89 & 93
451                  break;
452               case STD_BXROM:
453                  if (m_crc_hack)
454                     m_pcb_id = AVE_NINA01; // Mapper 34 is used for 2 diff boards
455                  break;
456               case BANDAI_LZ93:
457                  if (m_crc_hack)
458                     m_pcb_id = BANDAI_JUMP2;   // Mapper 153 is used for 2 diff boards
459                  break;
460               case IREM_HOLYDIV:
461                  if (m_crc_hack)
462                     m_pcb_id = JALECO_JF16;    // Mapper 78 is used for 2 diff boards
463                  break;
464               case CAMERICA_BF9093:
465                  if (m_crc_hack)
466                     m_pcb_id = CAMERICA_BF9097;    // Mapper 71 is used for 2 diff boards
467                  break;
468               case HES_BOARD:
469                  if (m_crc_hack)
470                     m_pcb_id = HES6IN1_BOARD;  // Mapper 113 is used for 2 diff boards
471                  break;
472               case WAIXING_ZS:
473                  if (m_crc_hack)
474                     m_pcb_id = WAIXING_DQ8;    // Mapper 242 is used for 2 diff boards
475                  break;
476               case BMC_GOLD_7IN1:
477                  if (m_crc_hack)
478                     m_pcb_id = BMC_MARIOPARTY_7IN1;    // Mapper 52 is used for 2 diff boards
479                  break;
480               case STD_EXROM:
481                  mapper_ram_size = 0x400;
482                  break;
483               case TAITO_X1_017:
484                  mapper_ram_size = 0x1400;
485                  break;
486               case TAITO_X1_005:
487               case TAITO_X1_005_A:
488                  mapper_ram_size = 0x80;
489                  break;
490               case NAMCOT_163:
491                  mapper_ram_size = 0x2000;
492                  break;
493               case FUKUTAKE_BOARD:
494                  mapper_ram_size = 2816;
495                  break;
496                  //FIXME: we also have to fix Action 52 PRG loading somewhere...
497            }
498           
499            // SETUP step 4: logging what we have found
500            if (!ines20)
501            {
502               logerror("Loaded game in iNES format:\n");
503               logerror("-- Mapper %d\n", mapper);
504               logerror("-- PRG 0x%x (%d x 16k chunks)\n", prg_size, prg_size / 0x4000);
505               logerror("-- VROM 0x%x (%d x 8k chunks)\n", vrom_size, vrom_size / 0x2000);
506               logerror("-- VRAM 0x%x (%d x 8k chunks)\n", vram_size, vram_size / 0x2000);
507               if (battery_size)
508                  logerror("-- Battery found\n");
509               if (has_trainer)
510                  logerror("-- Trainer found\n");
511               if (m_cart->get_four_screen_vram())
512                  logerror("-- 4-screen VRAM\n");
513               logerror("-- TV System: %s\n", ((header[10] & 3) == 0) ? "NTSC" : (header[10] & 1) ? "Both NTSC and PAL" : "PAL");
514            }
515            else
516            {
517               logerror("Loaded game in Extended iNES format:\n");
518               logerror("-- Mapper: %d\n", mapper);
519               logerror("-- Submapper: %d\n", (header[8] & 0xf0) >> 4);
520               logerror("-- PRG 0x%x (%d x 16k chunks)\n", prg_size, prg_size / 0x4000);
521               logerror("-- VROM 0x%x (%d x 8k chunks)\n", vrom_size, vrom_size / 0x2000);
522               logerror("-- VRAM 0x%x (%d x 8k chunks)\n", vram_size, vram_size / 0x2000);
523               logerror("-- PRG NVWRAM: %d\n", header[10] & 0x0f);
524               logerror("-- PRG WRAM: %d\n", (header[10] & 0xf0) >> 4);
525               logerror("-- CHR NVWRAM: %d\n", header[11] & 0x0f);
526               logerror("-- CHR WRAM: %d\n", (header[11] & 0xf0) >> 4);
527               logerror("-- TV System: %s\n", (header[12] & 2) ? "Both NTSC and PAL" : (header[12] & 1) ? "PAL" : "NTSC");
528            }
529           
530            // SETUP step 5: allocate pointers for PRG/VROM
531            if (prg_size)
532               m_cart->prg_alloc(machine(), prg_size);
533            if (vrom_size)
534               m_cart->vrom_alloc(machine(), vrom_size);
535           
536            if (has_trainer)
537               fread(&m_cart->m_prgram[0x1000], 0x200);
538           
539           
540            // SETUP step 6: at last load the data!
541            // Read in the program chunks
542            if (prg16k)
543            {
544               fread(m_cart->get_prg_base(), 0x4000);
545               memcpy(m_cart->get_prg_base() + 0x4000, m_cart->get_prg_base(), 0x4000);
546            }
547            else
548               fread(m_cart->get_prg_base(), m_cart->get_prg_size());
549#if SPLIT_PRG
550            {
551               FILE *prgout;
552               char outname[255];
553               
554               sprintf(outname, "%s.prg", filename());
555               prgout = fopen(outname, "wb");
556               if (prgout)
557               {
558                  fwrite(m_cart->get_prg_base(), 1, 0x4000 * m_cart->get_prg_size(), prgout);
559                  mame_printf_error("Created PRG chunk\n");
560               }
561               
562               fclose(prgout);
563            }
564#endif
565           
566            // Read in any chr chunks
567            if (m_cart->get_vrom_size())
568               fread(m_cart->get_vrom_base(), m_cart->get_vrom_size());
569           
570#if SPLIT_CHR
571            if (state->m_chr_chunks > 0)
572            {
573               FILE *chrout;
574               char outname[255];
575               
576               sprintf(outname, "%s.chr", filename());
577               chrout= fopen(outname, "wb");
578               if (chrout)
579               {
580                  fwrite(m_cart->get_vrom_base(), 1, m_cart->get_vrom_size(), chrout);
581                  mame_printf_error("Created CHR chunk\n");
582               }
583               fclose(chrout);
584            }
585#endif
586         }
587         else if ((magic[0] == 'U') && (magic[1] == 'N') && (magic[2] == 'I') && (magic[3] == 'F')) /* If header starts with 'UNIF' it is UNIF */
588         {
589            // SETUP step 1: running through the file and getting PRG, VROM sizes
590            UINT32 unif_ver = 0, chunk_length = 0, read_length = 0x20;
591            UINT32 prg_start = 0, chr_start = 0;
592            UINT32 size = length(), prg_size = 0, vrom_size = 0;
593            UINT8 buffer[4], mirror = 0;
594            char magic2[4];
595            char unif_mapr[32]; // here we should store MAPR chunks
596            bool mapr_chunk_found = FALSE, small_prg = FALSE;
597           
598            // allocate space to temporarily store PRG & CHR banks
599            UINT8 *temp_prg = auto_alloc_array(machine(), UINT8, 256 * 0x4000);
600            UINT8 *temp_chr = auto_alloc_array(machine(), UINT8, 256 * 0x2000);
601            UINT8 temp_byte = 0;
602           
603            fread(&buffer, 4);
604            unif_ver = buffer[0] | (buffer[1] << 8) | (buffer[2] << 16) | (buffer[3] << 24);
605            logerror("Loaded game in UNIF format, version %d\n", unif_ver);
606           
607            if (size <= 0x20)
608            {
609               logerror("%s only contains the UNIF header and no data.\n", filename());
610               return IMAGE_INIT_FAIL;
611            }
612           
613            do
614            {
615               fseek(read_length, SEEK_SET);
616               
617               memset(magic2, '\0', sizeof(magic2));
618               fread(&magic2, 4);
619               
620               /* We first run through the whole image to find a [MAPR] chunk. This is needed
621                because, unfortunately, the MAPR chunk is not always the first chunk (see
622                Super 24-in-1). When such a chunk is found, we set mapr_chunk_found=1 and
623                we go back to load other chunks! */
624               if (!mapr_chunk_found)
625               {
626                  if ((magic2[0] == 'M') && (magic2[1] == 'A') && (magic2[2] == 'P') && (magic2[3] == 'R'))
627                  {
628                     mapr_chunk_found = TRUE;
629                     logerror("[MAPR] chunk found: ");
630                     fread(&buffer, 4);
631                     chunk_length = buffer[0] | (buffer[1] << 8) | (buffer[2] << 16) | (buffer[3] << 24);
632                     
633                     if (chunk_length <= 0x20)
634                        fread(&unif_mapr, chunk_length);
635                     logerror("%s\n", unif_mapr);
636                     
637                     /* now that we found the MAPR chunk, we can go back to load other chunks */
638                     fseek(0x20, SEEK_SET);
639                     read_length = 0x20;
640                  }
641                  else
642                  {
643                     logerror("Skip this chunk. We need a [MAPR] chunk before anything else.\n");
644                     fread(&buffer, 4);
645                     chunk_length = buffer[0] | (buffer[1] << 8) | (buffer[2] << 16) | (buffer[3] << 24);
646                     
647                     read_length += (chunk_length + 8);
648                  }
649               }
650               else
651               {
652                  /* What kind of chunk do we have here? */
653                  if ((magic2[0] == 'M') && (magic2[1] == 'A') && (magic2[2] == 'P') && (magic2[3] == 'R'))
654                  {
655                     /* The [MAPR] chunk has already been read, so we skip it */
656                     /* TO DO: it would be nice to check if more than one MAPR chunk is present */
657                     logerror("[MAPR] chunk found (in the 2nd run). Already loaded.\n");
658                     fread(&buffer, 4);
659                     chunk_length = buffer[0] | (buffer[1] << 8) | (buffer[2] << 16) | (buffer[3] << 24);
660                     
661                     read_length += (chunk_length + 8);
662                  }
663                  else if ((magic2[0] == 'R') && (magic2[1] == 'E') && (magic2[2] == 'A') && (magic2[3] == 'D'))
664                  {
665                     logerror("[READ] chunk found. No support yet.\n");
666                     fread(&buffer, 4);
667                     chunk_length = buffer[0] | (buffer[1] << 8) | (buffer[2] << 16) | (buffer[3] << 24);
668                     
669                     read_length += (chunk_length + 8);
670                  }
671                  else if ((magic2[0] == 'N') && (magic2[1] == 'A') && (magic2[2] == 'M') && (magic2[3] == 'E'))
672                  {
673                     logerror("[NAME] chunk found. No support yet.\n");
674                     fread(&buffer, 4);
675                     chunk_length = buffer[0] | (buffer[1] << 8) | (buffer[2] << 16) | (buffer[3] << 24);
676                     
677                     read_length += (chunk_length + 8);
678                  }
679                  else if ((magic2[0] == 'W') && (magic2[1] == 'R') && (magic2[2] == 'T') && (magic2[3] == 'R'))
680                  {
681                     logerror("[WRTR] chunk found. No support yet.\n");
682                     fread(&buffer, 4);
683                     chunk_length = buffer[0] | (buffer[1] << 8) | (buffer[2] << 16) | (buffer[3] << 24);
684                     
685                     read_length += (chunk_length + 8);
686                  }
687                  else if ((magic2[0] == 'T') && (magic2[1] == 'V') && (magic2[2] == 'C') && (magic2[3] == 'I'))
688                  {
689                     logerror("[TVCI] chunk found.\n");
690                     fread(&buffer, 4);
691                     chunk_length = buffer[0] | (buffer[1] << 8) | (buffer[2] << 16) | (buffer[3] << 24);
692                     
693                     fread(&temp_byte, 1);
694                     logerror("Television Standard : %s\n", (temp_byte == 0) ? "NTSC" : (temp_byte == 1) ? "PAL" : "Does not matter");
695                     
696                     read_length += (chunk_length + 8);
697                  }
698                  else if ((magic2[0] == 'T') && (magic2[1] == 'V') && (magic2[2] == 'S') && (magic2[3] == 'C')) // is this the same as TVCI??
699                  {
700                     logerror("[TVSC] chunk found. No support yet.\n");
701                     fread(&buffer, 4);
702                     chunk_length = buffer[0] | (buffer[1] << 8) | (buffer[2] << 16) | (buffer[3] << 24);
703                     
704                     read_length += (chunk_length + 8);
705                  }
706                  else if ((magic2[0] == 'D') && (magic2[1] == 'I') && (magic2[2] == 'N') && (magic2[3] == 'F'))
707                  {
708                     logerror("[DINF] chunk found. No support yet.\n");
709                     fread(&buffer, 4);
710                     chunk_length = buffer[0] | (buffer[1] << 8) | (buffer[2] << 16) | (buffer[3] << 24);
711                     
712                     read_length += (chunk_length + 8);
713                  }
714                  else if ((magic2[0] == 'C') && (magic2[1] == 'T') && (magic2[2] == 'R') && (magic2[3] == 'L'))
715                  {
716                     logerror("[CTRL] chunk found. No support yet.\n");
717                     fread(&buffer, 4);
718                     chunk_length = buffer[0] | (buffer[1] << 8) | (buffer[2] << 16) | (buffer[3] << 24);
719                     
720                     read_length += (chunk_length + 8);
721                  }
722                  else if ((magic2[0] == 'B') && (magic2[1] == 'A') && (magic2[2] == 'T') && (magic2[3] == 'R'))
723                  {
724                     logerror("[BATR] chunk found. No support yet.\n");
725                     fread(&buffer, 4);
726                     chunk_length = buffer[0] | (buffer[1] << 8) | (buffer[2] << 16) | (buffer[3] << 24);
727                     
728                     read_length += (chunk_length + 8);
729                  }
730                  else if ((magic2[0] == 'V') && (magic2[1] == 'R') && (magic2[2] == 'O') && (magic2[3] == 'R'))
731                  {
732                     logerror("[VROR] chunk found. No support yet.\n");
733                     fread(&buffer, 4);
734                     chunk_length = buffer[0] | (buffer[1] << 8) | (buffer[2] << 16) | (buffer[3] << 24);
735                     
736                     read_length += (chunk_length + 8);
737                  }
738                  else if ((magic2[0] == 'M') && (magic2[1] == 'I') && (magic2[2] == 'R') && (magic2[3] == 'R'))
739                  {
740                     logerror("[MIRR] chunk found.\n");
741                     fread(&buffer, 4);
742                     chunk_length = buffer[0] | (buffer[1] << 8) | (buffer[2] << 16) | (buffer[3] << 24);
743                     
744                     fread(&mirror, 1);
745                     
746                     read_length += (chunk_length + 8);
747                  }
748                  else if ((magic2[0] == 'P') && (magic2[1] == 'C') && (magic2[2] == 'K'))
749                  {
750                     logerror("[PCK%c] chunk found. No support yet.\n", magic2[3]);
751                     fread(&buffer, 4);
752                     chunk_length = buffer[0] | (buffer[1] << 8) | (buffer[2] << 16) | (buffer[3] << 24);
753                     
754                     read_length += (chunk_length + 8);
755                  }
756                  else if ((magic2[0] == 'C') && (magic2[1] == 'C') && (magic2[2] == 'K'))
757                  {
758                     logerror("[CCK%c] chunk found. No support yet.\n", magic2[3]);
759                     fread(&buffer, 4);
760                     chunk_length = buffer[0] | (buffer[1] << 8) | (buffer[2] << 16) | (buffer[3] << 24);
761                     
762                     read_length += (chunk_length + 8);
763                  }
764                  else if ((magic2[0] == 'P') && (magic2[1] == 'R') && (magic2[2] == 'G'))
765                  {
766                     logerror("[PRG%c] chunk found. ", magic2[3]);
767                     fread(&buffer, 4);
768                     chunk_length = buffer[0] | (buffer[1] << 8) | (buffer[2] << 16) | (buffer[3] << 24);
769                     prg_size += chunk_length;
770                     
771                     if (chunk_length / 0x4000)
772                        logerror("It consists of %d 16K-blocks.\n", chunk_length / 0x4000);
773                     else
774                     {
775                        small_prg = TRUE;
776                        logerror("This chunk is smaller than 16K: the emulation might have issues. Please report this file to the MESS forums.\n");
777                     }
778                     
779                     /* Read in the program chunks */
780                     fread(&temp_prg[prg_start], chunk_length);
781                     
782                     prg_start += chunk_length;
783                     read_length += (chunk_length + 8);
784                  }
785                  else if ((magic2[0] == 'C') && (magic2[1] == 'H') && (magic2[2] == 'R'))
786                  {
787                     logerror("[CHR%c] chunk found. ", magic2[3]);
788                     fread(&buffer, 4);
789                     chunk_length = buffer[0] | (buffer[1] << 8) | (buffer[2] << 16) | (buffer[3] << 24);
790                     vrom_size += chunk_length;
791                     
792                     logerror("It consists of %d 8K-blocks.\n", chunk_length / 0x2000);
793                     
794                     /* Read in the vrom chunks */
795                     fread(&temp_chr[chr_start], chunk_length);
796                     
797                     chr_start += chunk_length;
798                     read_length += (chunk_length + 8);
799                  }
800                  else
801                  {
802                     logerror("Unsupported UNIF chunk or corrupted header. Please report the problem at MESS Board.\n");
803                     read_length = size;
804                  }
805               }
806            } while (size > read_length);
807           
808            if (!mapr_chunk_found)
809            {
810               auto_free(machine(), temp_prg);
811               auto_free(machine(), temp_chr);
812               fatalerror("UNIF should have a [MAPR] chunk to work. Check if your image has been corrupted\n");
813            }
814           
815            if (!prg_start)
816            {
817               auto_free(machine(), temp_prg);
818               auto_free(machine(), temp_chr);
819               fatalerror("No PRG found. Please report the problem at MESS Board.\n");
820            }
821           
822            // SETUP step 2: getting PCB and other settings
823            int pcb_id = 0, battery = 0, prgram = 0, vram_chunks = 0;
824            unif_mapr_setup(unif_mapr, &pcb_id, &battery, &prgram, &vram_chunks);
825           
826            // SETUP step 3: storing the info needed for emulation
827            m_pcb_id = pcb_id;
828            if (battery)
829               battery_size = NES_BATTERY_SIZE; // we should allow for smaller battery!
830            prgram_size = prgram * 0x2000;
831            vram_size = vram_chunks * 0x2000;
832           
833            m_cart->set_four_screen_vram(0);
834            switch (mirror)
835            {
836               case 0: // Horizontal Mirroring (Hard Wired)
837                  m_cart->set_mirroring(PPU_MIRROR_HORZ);
838                  break;
839               case 1: // Vertical Mirroring (Hard Wired)
840                  m_cart->set_mirroring(PPU_MIRROR_VERT);
841                  break;
842               case 2: // Mirror All Pages From $2000 (Hard Wired)
843                  m_cart->set_mirroring(PPU_MIRROR_LOW);
844                  break;
845               case 3: // Mirror All Pages From $2400 (Hard Wired)
846                  m_cart->set_mirroring(PPU_MIRROR_HIGH);
847                  break;
848               case 4: // Four Screens of VRAM (Hard Wired)
849                  m_cart->set_four_screen_vram(1);
850                  break;
851               case 5: // Mirroring Controlled By Mapper Hardware
852                  logerror("Mirroring handled by the board hardware.\n");
853                  // default to horizontal at start
854                  m_cart->set_mirroring(PPU_MIRROR_HORZ);
855                  break;
856               default:
857                  logerror("Undocumented mirroring value.\n");
858                  // default to horizontal
859                  m_cart->set_mirroring(PPU_MIRROR_HORZ);
860                  break;
861            }
862           
863            // SETUP step 4: logging what we have found
864            logerror("-- Board %s\n", unif_mapr);
865            logerror("-- PRG 0x%x (%d x 16k chunks)\n", prg_size, prg_size / 0x4000);
866            logerror("-- VROM 0x%x (%d x 8k chunks)\n", vrom_size, vrom_size / 0x2000);
867            logerror("-- VRAM 0x%x (%d x 8k chunks)\n", vram_size, vram_size / 0x2000);
868           
869            // SETUP steps 5/6: allocate pointers for PRG/VROM and load the data!
870            if (prg_size == 0x4000)
871            {
872               m_cart->prg_alloc(machine(), 0x8000);
873               memcpy(m_cart->get_prg_base(), temp_prg, 0x4000);
874               memcpy(m_cart->get_prg_base() + 0x4000, m_cart->get_prg_base(), 0x4000);
875            }
876            else
877            {
878               m_cart->prg_alloc(machine(), prg_size);
879               memcpy(m_cart->get_prg_base(), temp_prg, prg_size);
880            }
881           
882            if (small_prg)  // This is not supported yet, so warn users about this
883               mame_printf_error("Loaded UNIF file with non-16k PRG chunk. This is not supported in MESS yet.");
884           
885            if (vrom_size)
886            {
887               m_cart->vrom_alloc(machine(), vrom_size);
888               memcpy(m_cart->get_vrom_base(), temp_chr, vrom_size);
889            }
890
891#if SPLIT_PRG
892            {
893               FILE *prgout;
894               char outname[255];
895               
896               sprintf(outname, "%s.prg", filename());
897               prgout = fopen(outname, "wb");
898               if (prgout)
899               {
900                  fwrite(m_cart->get_prg_base(), 1, 0x4000 * m_cart->get_prg_size(), prgout);
901                  mame_printf_error("Created PRG chunk\n");
902               }
903               
904               fclose(prgout);
905            }
906#endif
907           
908#if SPLIT_CHR
909            if (state->m_chr_chunks > 0)
910            {
911               FILE *chrout;
912               char outname[255];
913               
914               sprintf(outname, "%s.chr", filename());
915               chrout= fopen(outname, "wb");
916               if (chrout)
917               {
918                  fwrite(m_cart->get_vrom_base(), 1, m_cart->get_vrom_size(), chrout);
919                  mame_printf_error("Created CHR chunk\n");
920               }
921               fclose(chrout);
922            }
923#endif
924            // free the temporary copy of PRG/CHR
925            auto_free(machine(), temp_prg);
926            auto_free(machine(), temp_chr);
927            logerror("UNIF support is only very preliminary.\n");
928         }
929         else
930         {
931            logerror("%s is NOT a file in either iNES or UNIF format.\n", filename());
932            return IMAGE_INIT_FAIL;
933         }
934      }
935      else
936      {
937         // SETUP step 1: getting PRG, VROM, VRAM sizes
938         UINT32 prg_size = get_software_region_length("prg");
939         UINT32 vrom_size = get_software_region_length("chr");
940         UINT32 vram_size = get_software_region_length("vram");
941         vram_size += get_software_region_length("vram2");
942         
943         // validate the xml fields
944         if (!prg_size)
945            fatalerror("No PRG entry for this software! Please check if the xml list got corrupted\n");
946         if (prg_size < 0x8000)
947            fatalerror("PRG entry is too small! Please check if the xml list got corrupted\n");
948         
949         // SETUP step 2: getting PCB and other settings
950         if (get_feature("pcb"))
951            m_pcb_id = nes_get_pcb_id(machine(), get_feature("pcb"));
952         else
953            m_pcb_id = NO_BOARD;
954         
955         // SETUP step 3: storing the info needed for emulation
956         if (m_pcb_id == STD_TVROM || m_pcb_id == STD_DRROM || m_pcb_id == IREM_LROG017)
957            m_cart->set_four_screen_vram(1);
958         else
959            m_cart->set_four_screen_vram(0);
960         
961         if (get_software_region("bwram") != NULL)
962            battery_size = get_software_region_length("bwram");
963         
964         if (m_pcb_id == BANDAI_LZ93EX)
965         {
966            // allocate the 24C01 or 24C02 EEPROM
967            battery_size += 0x2000;
968         }
969         
970         if (m_pcb_id == BANDAI_DATACH)
971         {
972            // allocate the 24C01 and 24C02 EEPROM
973            battery_size += 0x4000;
974         }
975         
976         if (get_software_region("wram") != NULL)
977            prgram_size = get_software_region_length("wram");
978         if (get_software_region("mapper_ram") != NULL)
979            mapper_ram_size = get_software_region_length("mapper_ram");
980         if (get_software_region("mapper_bram") != NULL)
981            mapper_bram_size = get_software_region_length("mapper_bram");
982         
983         if (get_feature("mirroring"))
984         {
985            const char *mirroring = get_feature("mirroring");
986            if (!strcmp(mirroring, "horizontal"))
987               m_cart->set_mirroring(PPU_MIRROR_HORZ);
988            if (!strcmp(mirroring, "vertical"))
989               m_cart->set_mirroring(PPU_MIRROR_VERT);
990            if (!strcmp(mirroring, "high"))
991               m_cart->set_mirroring(PPU_MIRROR_HIGH);
992            if (!strcmp(mirroring, "low"))
993               m_cart->set_mirroring(PPU_MIRROR_LOW);
994         }
995         else
996            m_cart->set_mirroring(PPU_MIRROR_NONE);
997         
998         /* Check for pins in specific boards which require them */
999         if (m_pcb_id == STD_CNROM)
1000         {
1001            if (get_feature("chr-pin26") != NULL)
1002            {
1003               m_ce_mask |= 0x01;
1004               m_ce_state |= !strcmp(get_feature("chr-pin26"), "CE") ? 0x01 : 0;
1005            }
1006            if (get_feature("chr-pin27") != NULL)
1007            {
1008               m_ce_mask |= 0x02;
1009               m_ce_state |= !strcmp(get_feature("chr-pin27"), "CE") ? 0x02 : 0;
1010            }
1011         }
1012         
1013         if (m_pcb_id == TAITO_X1_005 && get_feature("x1-pin17") != NULL && get_feature("x1-pin31") != NULL)
1014         {
1015            if (!strcmp(get_feature("x1-pin17"), "CIRAM A10") && !strcmp(get_feature("x1-pin31"), "NC"))
1016               m_pcb_id = TAITO_X1_005_A;
1017         }
1018         
1019         if (m_pcb_id == KONAMI_VRC2)
1020         {
1021            m_vrc_ls_prg_a = nes_cart_get_line(get_feature("vrc2-pin3"));
1022            m_vrc_ls_prg_b = nes_cart_get_line(get_feature("vrc2-pin4"));
1023            m_vrc_ls_chr = (nes_cart_get_line(get_feature("vrc2-pin21")) != 10) ? 1 : 0;
1024//          mame_printf_error("VRC-2, pin3: A%d, pin4: A%d, pin21: %s\n", state->m_vrc_ls_prg_a, state->m_vrc_ls_prg_b, state->m_vrc_ls_chr ? "NC" : "A10");
1025         }
1026         
1027         if (m_pcb_id == KONAMI_VRC4)
1028         {
1029            m_vrc_ls_prg_a = nes_cart_get_line(get_feature("vrc4-pin3"));
1030            m_vrc_ls_prg_b = nes_cart_get_line(get_feature("vrc4-pin4"));
1031//          mame_printf_error("VRC-4, pin3: A%d, pin4: A%d\n", state->m_vrc_ls_prg_a, state->m_vrc_ls_prg_b);
1032         }
1033         
1034         if (m_pcb_id == KONAMI_VRC6)
1035         {
1036            m_vrc_ls_prg_a = nes_cart_get_line(get_feature("vrc6-pin9"));
1037            m_vrc_ls_prg_b = nes_cart_get_line(get_feature("vrc6-pin10"));
1038//          mame_printf_error("VRC-6, pin9: A%d, pin10: A%d\n", state->m_vrc_ls_prg_a, state->m_vrc_ls_prg_b);
1039         }
1040         
1041         /* Check for other misc board variants */
1042         if (m_pcb_id == STD_SOROM)
1043         {
1044            if (get_feature("mmc1_type") != NULL && !strcmp(get_feature("mmc1_type"), "MMC1A"))
1045               m_pcb_id = STD_SOROM_A;    // in MMC1-A PRG RAM is always enabled
1046         }
1047         
1048         if (m_pcb_id == STD_SXROM)
1049         {
1050            if (get_feature("mmc1_type") != NULL && !strcmp(get_feature("mmc1_type"), "MMC1A"))
1051               m_pcb_id = STD_SXROM_A;    // in MMC1-A PRG RAM is always enabled
1052         }
1053         
1054         if (m_pcb_id == STD_NXROM || m_pcb_id == SUNSOFT_DCS)
1055         {
1056            if (get_software_region("minicart") != NULL)    // check for dual minicart
1057            {
1058               m_pcb_id = SUNSOFT_DCS;
1059               // we shall load somewhere the minicart, but we still do not support this
1060            }
1061         }
1062         
1063         // SETUP step 4: logging what we have found
1064         logerror("Loaded game from softlist:\n");
1065         logerror("-- PCB: %s", get_feature("pcb"));
1066         if (m_pcb_id == UNSUPPORTED_BOARD)
1067            logerror(" (currently not supported by MESS)");
1068         logerror("\n-- PRG 0x%x (%d x 16k chunks)\n", prg_size, prg_size / 0x4000);
1069         logerror("-- VROM 0x%x (%d x 8k chunks)\n", vrom_size, vrom_size / 0x2000);
1070         logerror("-- VRAM 0x%x (%d x 8k chunks)\n", vram_size, vram_size / 0x2000);
1071         logerror("-- PRG NVWRAM: %d\n", m_cart->get_battery_size());
1072         logerror("-- PRG WRAM: %d\n",  m_cart->get_prgram_size());
1073         
1074         // SETUP steps 5/6: allocate pointers for PRG/VROM and load the data!
1075         m_cart->prg_alloc(machine(), prg_size);
1076         memcpy(m_cart->get_prg_base(), get_software_region("prg"), prg_size);
1077         if (vrom_size)
1078         {
1079            m_cart->vrom_alloc(machine(), vrom_size);
1080            memcpy(m_cart->get_vrom_base(), get_software_region("chr"), vrom_size);
1081         }
1082      }
1083   
1084      // Allocate the remaining pointer, when needed
1085      if (vram_size)
1086         m_cart->vram_alloc(machine(), vram_size);
1087      if (prgram_size)
1088         m_cart->prgram_alloc(machine(), prgram_size);
1089      if (mapper_ram_size)
1090         m_cart->mapper_ram_alloc(machine(), mapper_ram_size);
1091     
1092      // Attempt to load a battery file for this ROM
1093      // A few boards have internal RAM with a battery (MMC6, Taito X1-005 & X1-017, etc.)
1094      if (battery_size || mapper_bram_size)
1095      {
1096         UINT32 tot_size = battery_size + mapper_bram_size;
1097         UINT8 *temp_nvram = auto_alloc_array(machine(), UINT8, tot_size);
1098         battery_load(temp_nvram, tot_size, 0x00);
1099         if (battery_size)
1100         {
1101            m_cart->battery_alloc(machine(), battery_size);
1102            memcpy(m_cart->get_battery_base(), temp_nvram, battery_size);
1103         }
1104         if (mapper_bram_size)
1105         {
1106            m_cart->mapper_bram_alloc(machine(), mapper_bram_size);
1107            memcpy(m_cart->get_mapper_bram_base(), temp_nvram + battery_size, mapper_bram_size);
1108         }
1109         
1110         if (temp_nvram)
1111            auto_free(machine(), temp_nvram);
1112      }
1113   }
1114   
1115   return IMAGE_INIT_PASS;
1116}
1117
1118
1119/*-------------------------------------------------
1120 call_unloadload
1121 -------------------------------------------------*/
1122
1123void base_nes_cart_slot_device::call_unload()
1124{
1125   if (m_cart->get_battery_size())
1126      battery_save(m_cart->get_battery_base(), m_cart->get_battery_size());
1127   if (m_cart->get_mapper_bram_size())
1128      battery_save(m_cart->get_mapper_bram_base(), m_cart->get_mapper_bram_size());
1129}
1130
1131
1132/*-------------------------------------------------
1133 call softlist load
1134 -------------------------------------------------*/
1135
1136bool base_nes_cart_slot_device::call_softlist_load(char *swlist, char *swname, rom_entry *start_entry)
1137{
1138   load_software_part_region(this, swlist, swname, start_entry );
1139   return TRUE;
1140}
1141
1142/*-------------------------------------------------
1143 get default card software
1144 -------------------------------------------------*/
1145
1146const char * base_nes_cart_slot_device::get_default_card_software(const machine_config &config, emu_options &options)
1147{
1148   return software_get_default_slot(config, options, this, "rom");
1149}
1150
1151
1152/*-------------------------------------------------
1153 read
1154 -------------------------------------------------*/
1155
1156READ8_MEMBER(base_nes_cart_slot_device::read_l)
1157{
1158   if (m_cart)
1159      return m_cart->read_l(space, offset);
1160   else
1161      return 0xff;
1162}
1163
1164READ8_MEMBER(base_nes_cart_slot_device::read_m)
1165{
1166   if (m_cart)
1167      return m_cart->read_m(space, offset);
1168   else
1169      return 0xff;
1170}
1171
1172READ8_MEMBER(base_nes_cart_slot_device::read_h)
1173{
1174   if (m_cart)
1175      return m_cart->read_h(space, offset);
1176   else
1177      return 0xff;
1178}
1179
1180
1181/*-------------------------------------------------
1182 write
1183 -------------------------------------------------*/
1184
1185WRITE8_MEMBER(base_nes_cart_slot_device::write_l)
1186{
1187   if (m_cart)
1188      m_cart->write_l(space, offset, data);
1189}
1190
1191WRITE8_MEMBER(base_nes_cart_slot_device::write_m)
1192{
1193   if (m_cart)
1194      m_cart->write_m(space, offset, data);
1195}
1196
1197WRITE8_MEMBER(base_nes_cart_slot_device::write_h)
1198{
1199   if (m_cart)
1200      m_cart->write_h(space, offset, data);
1201}
1202
1203
1204// CART DEVICE [TO BE MOVED TO SEPARATE SOURCE LATER]
1205
1206//-------------------------------------------------
1207//  nes_rom_device - constructor
1208//-------------------------------------------------
1209
1210const device_type NES_ROM = &device_creator<nes_rom_device>;
1211
1212nes_rom_device::nes_rom_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
1213               : device_t(mconfig, NES_ROM, "NES ROM", tag, owner, clock),
1214               device_nes_cart_interface( mconfig, *this )
1215{
1216}
1217
1218nes_rom_device::nes_rom_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock)
1219               : device_t(mconfig, type, name, tag, owner, clock),
1220               device_nes_cart_interface( mconfig, *this )
1221{
1222}
1223
1224//-------------------------------------------------
1225//  device_start - device-specific startup
1226//-------------------------------------------------
1227
1228void nes_rom_device::device_start()
1229{
1230}
1231
Property changes on: trunk/src/mess/machine/nes_slot.c
Added: svn:eol-style
   + native
Added: svn:mime-type
   + text/plain
trunk/src/mess/machine/nes_slot.h
r0r20931
1#ifndef __NES_SLOT_H__
2#define __NES_SLOT_H__
3
4#include "includes/nes_mmc.h"
5
6
7/***************************************************************************
8 TYPE DEFINITIONS
9 ***************************************************************************/
10
11// ======================> nes_cart_interface
12
13struct nes_cart_interface
14{
15};
16
17
18// ======================> device_nes_cart_interface
19
20class device_nes_cart_interface : public device_slot_card_interface
21{
22public:
23   // construction/destruction
24   device_nes_cart_interface(const machine_config &mconfig, device_t &device);
25   virtual ~device_nes_cart_interface();
26   
27   // reading and writing
28   virtual DECLARE_READ8_MEMBER(read_l) { return 0xff; }
29   virtual DECLARE_READ8_MEMBER(read_m) { return 0xff; }
30   virtual DECLARE_READ8_MEMBER(read_h) { return 0xff; }
31   virtual DECLARE_WRITE8_MEMBER(write_l) { }
32   virtual DECLARE_WRITE8_MEMBER(write_m) { }
33   virtual DECLARE_WRITE8_MEMBER(write_h) { }
34   
35   virtual void prg_alloc(running_machine &machine, size_t size);
36   virtual void prgram_alloc(running_machine &machine, size_t size);
37   virtual void vrom_alloc(running_machine &machine, size_t size);
38   virtual void vram_alloc(running_machine &machine, size_t size);
39   virtual void battery_alloc(running_machine &machine, size_t size);
40   virtual void mapper_ram_alloc(running_machine &machine, size_t size);
41   virtual void mapper_bram_alloc(running_machine &machine, size_t size);
42   
43   virtual int get_mirroring() { return m_mirroring; }
44   virtual void set_mirroring(int val) { m_mirroring = val; }
45   virtual int get_four_screen_vram() { return m_four_screen_vram; }
46   virtual void set_four_screen_vram(int val) { m_four_screen_vram = val; }
47   
48   virtual UINT8* get_prg_base() { return m_prg; }
49   virtual UINT8* get_prgram_base() { return m_prgram; }
50   virtual UINT8* get_vrom_base() { return m_vrom; }
51   virtual UINT8* get_vram_base() { return m_vram; }
52   virtual UINT8* get_battery_base() { return m_battery; }
53   virtual UINT8* get_mapper_ram_base() { return m_mapper_ram; }
54   virtual UINT8* get_mapper_bram_base() { return m_mapper_bram; }
55
56   virtual UINT32 get_prg_size() { return m_prg_size; }
57   virtual UINT32 get_prgram_size() { return m_prgram_size; }
58   virtual UINT32 get_vrom_size() { return m_vrom_size; }
59   virtual UINT32 get_vram_size() { return m_vram_size; }
60   virtual UINT32 get_battery_size() { return m_battery_size; }
61   virtual UINT32 get_mapper_ram_size() { return m_mapper_ram_size; }
62   virtual UINT32 get_mapper_bram_size() { return m_mapper_bram_size; }
63   
64//private:
65   
66   // internal state
67   UINT8      *m_prg;
68   UINT8      *m_prgram;
69   UINT8      *m_vrom;
70   UINT8      *m_vram;
71   UINT8      *m_battery;
72   UINT8      *m_mapper_ram;
73   UINT8      *m_mapper_bram;
74   
75   UINT32 m_prg_size;
76   UINT32 m_prgram_size;
77   UINT32 m_vrom_size;
78   UINT32 m_vram_size;
79   UINT32 m_battery_size;
80   UINT32 m_mapper_ram_size;
81   UINT32 m_mapper_bram_size;
82
83   int m_mirroring, m_four_screen_vram;
84   bool m_has_battery, m_has_prgram;
85};
86
87
88// ======================> nes_cart_slot_device
89
90class base_nes_cart_slot_device : public device_t,
91                        public nes_cart_interface,
92                        public device_image_interface,
93                        public device_slot_interface
94{
95public:
96   // construction/destruction
97   base_nes_cart_slot_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock);
98   virtual ~base_nes_cart_slot_device();
99   
100   // device-level overrides
101   virtual void device_start();
102   virtual void device_config_complete();
103   
104   // image-level overrides
105   virtual bool call_load();
106   virtual void call_unload();
107   virtual bool call_softlist_load(char *swlist, char *swname, rom_entry *start_entry);
108   
109   virtual iodevice_t image_type() const { return IO_CARTSLOT; }
110   virtual bool is_readable()  const { return 1; }
111   virtual bool is_writeable() const { return 0; }
112   virtual bool is_creatable() const { return 0; }
113   virtual bool must_be_loaded() const { return 1; }
114   virtual bool is_reset_on_load() const { return 0; }
115   virtual const char *image_interface() const { return "nes_cart"; }
116   virtual const char *file_extensions() const { return "nes,unf,unif"; }
117   virtual const option_guide *create_option_guide() const { return NULL; }
118   
119   // slot interface overrides
120   virtual const char * get_default_card_software(const machine_config &config, emu_options &options);
121   
122   // reading and writing
123   virtual DECLARE_READ8_MEMBER(read_l);
124   virtual DECLARE_READ8_MEMBER(read_m);
125   virtual DECLARE_READ8_MEMBER(read_h);
126   virtual DECLARE_WRITE8_MEMBER(write_l);
127   virtual DECLARE_WRITE8_MEMBER(write_m);
128   virtual DECLARE_WRITE8_MEMBER(write_h);
129
130   int get_pcb_id() { return m_pcb_id; };
131   
132   // temporarily here
133   int m_chr_open_bus;
134   int m_ce_mask;
135   int m_ce_state;
136   int m_vrc_ls_prg_a;
137   int m_vrc_ls_prg_b;
138   int m_vrc_ls_chr;
139   int m_crc_hack;
140   
141   virtual int get_chr_open_bus() { return m_chr_open_bus; };
142   virtual int get_ce_mask() { return m_ce_mask; };
143   virtual int get_ce_state() { return m_ce_state; };
144   virtual int get_vrc_ls_prg_a() { return m_vrc_ls_prg_a; };
145   virtual int get_vrc_ls_prg_b() { return m_vrc_ls_prg_b; };
146   virtual int get_vrc_ls_chr() { return m_vrc_ls_chr; };
147   virtual int get_crc_hack() { return m_crc_hack; };
148   
149   //private:
150   
151   device_nes_cart_interface*      m_cart;
152   int m_pcb_id;
153};
154
155// ======================> nes_cart_slot_device
156
157class nes_cart_slot_device :  public base_nes_cart_slot_device
158{
159public:
160   // construction/destruction
161   nes_cart_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
162   virtual bool must_be_loaded() const { return 1; }
163};
164
165
166// ======================> fc_cart_slot_device
167
168class fc_cart_slot_device :  public base_nes_cart_slot_device
169{
170public:
171   // construction/destruction
172   fc_cart_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
173   virtual bool must_be_loaded() const { return 0; }
174};
175
176
177// device type definition
178extern const device_type NES_CART_SLOT;
179extern const device_type FC_CART_SLOT;   // same but not mandatory
180
181
182/***************************************************************************
183 DEVICE CONFIGURATION MACROS
184 ***************************************************************************/
185
186#define MCFG_NES_CARTRIDGE_ADD(_tag,_config,_slot_intf,_def_slot,_def_inp) \
187   MCFG_DEVICE_ADD(_tag, NES_CART_SLOT, 0) \
188   MCFG_DEVICE_CONFIG(_config) \
189   MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_slot, _def_inp, false)
190
191#define MCFG_FC_CARTRIDGE_ADD(_tag,_config,_slot_intf,_def_slot,_def_inp) \
192   MCFG_DEVICE_ADD(_tag, FC_CART_SLOT, 0) \
193   MCFG_DEVICE_CONFIG(_config) \
194   MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_slot, _def_inp, false)
195
196
197// CART DEVICE [TO BE MOVED TO SEPARATE SOURCE LATER]
198
199//**************************************************************************
200//  TYPE DEFINITIONS
201//**************************************************************************
202
203// ======================> nes_rom_device
204
205class nes_rom_device : public device_t,
206            public device_nes_cart_interface
207{
208public:
209   // construction/destruction
210   nes_rom_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
211   nes_rom_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock);
212   
213   //protected:
214   // device-level overrides
215   virtual void device_start();
216   virtual void device_config_complete() { m_shortname = "nes_rom"; }
217   
218   // nescart_interface overrides
219//   virtual DECLARE_READ8_MEMBER(read_l);
220//   virtual DECLARE_READ8_MEMBER(read_m);
221//   virtual DECLARE_READ8_MEMBER(read_h);
222//   virtual DECLARE_WRITE8_MEMBER(write_l);
223//   virtual DECLARE_WRITE8_MEMBER(write_m);
224//   virtual DECLARE_WRITE8_MEMBER(write_h);
225};
226
227// device type definition
228extern const device_type NES_ROM;
229
230#endif
Property changes on: trunk/src/mess/machine/nes_slot.h
Added: svn:eol-style
   + native
Added: svn:mime-type
   + text/plain
trunk/src/mess/machine/nes_mmc.c
r20930r20931
209209   return m_nt_page[page].access[offset & 0x3ff];
210210}
211211
212WRITE8_MEMBER(nes_state::nes_low_mapper_w)
213{
214   if (!m_mmc_write_low.isnull())
215      (m_mmc_write_low)(space, offset, data, mem_mask);
216   else
217      logerror("Unimplemented LOW mapper write, offset: %04x, data: %02x\n", offset + 0x4100, data);
218}
219
220READ8_MEMBER(nes_state::nes_low_mapper_r)
221{
222   if (!m_mmc_read_low.isnull())
223      return (m_mmc_read_low)(space, offset, mem_mask);
224   else
225      logerror("Unimplemented LOW mapper read, offset: %04x\n", offset + 0x4100);
226
227   return 0;
228}
229
230212/*************************************************************
231213
232214    Helpers to handle MMC
trunk/src/mess/machine/nes_unif.c
r20930r20931
158158
159159 *************************************************************/
160160
161void unif_mapr_setup( running_machine &machine, const char *board )
161void unif_mapr_setup( const char *board, int *pcb_id, int *battery, int *prgram, int *vram_chunks )
162162{
163   nes_state *state = machine.driver_data<nes_state>();
164   const unif *unif_board = nes_unif_lookup(board);
165
166   logerror("%s\n", board);
167
163   const unif *unif_board = nes_unif_lookup(board);     
168164   if (unif_board == NULL)
169165      fatalerror("Unknown UNIF board %s.\n", board);
170
171   state->m_pcb_id = unif_board->board_idx;
172   state->m_battery = unif_board->nvwram;  // we should implement battery banks based on the size of this...
173   state->m_battery_size = NES_BATTERY_SIZE; // FIXME: we should allow for smaller battery!
174   state->m_prg_ram = unif_board->wram;    // we should implement WRAM banks based on the size of this...
175
166   
167   *pcb_id = unif_board->board_idx;
168   *battery = unif_board->nvwram;   // we should implement battery banks based on the size of this...
169   *prgram = unif_board->wram;   // we should implement WRAM banks based on the size of this...
170   
176171   if (unif_board->chrram <= CHRRAM_8)
177      state->m_vram_chunks = 1;
172      *vram_chunks = 1;
178173   else if (unif_board->chrram == CHRRAM_16)
179      state->m_vram_chunks = 2;
174      *vram_chunks = 2;
180175   else if (unif_board->chrram == CHRRAM_32)
181      state->m_vram_chunks = 4;
176      *vram_chunks = 4;
182177}
trunk/src/mess/includes/nes.h
r20930r20931
1010#define NES_H_
1111
1212#include "includes/nes_mmc.h"
13#include "machine/nes_slot.h"
1314
1415
1516/***************************************************************************
r20930r20931
5455{
5556public:
5657   nes_state(const machine_config &mconfig, device_type type, const char *tag)
57   : nes_carts_state(mconfig, type, tag) { }
58      : nes_carts_state(mconfig, type, tag),
59      m_cartslot(*this, "nes_slot")
60   { }
5861
5962   /* input_related - this part has to be cleaned up (e.g. in_2 and in_3 are not really necessary here...) */
6063   nes_input m_in_0, m_in_1, m_in_2, m_in_3;
r20930r20931
7477   DECLARE_READ8_MEMBER(nes_chr_r);
7578   DECLARE_WRITE8_MEMBER(nes_nt_w);
7679   DECLARE_READ8_MEMBER(nes_nt_r);
77   DECLARE_WRITE8_MEMBER(nes_low_mapper_w);
78   DECLARE_READ8_MEMBER(nes_low_mapper_r);
7980
8081   /* misc */
8182   write8_delegate   m_mmc_write_low;
r20930r20931
114115   DECLARE_WRITE8_MEMBER(nes_vh_sprite_dma_w);
115116   DECLARE_DRIVER_INIT(famicom);
116117   virtual void machine_start();
117   virtual void machine_stop();
118118   virtual void machine_reset();
119119   virtual void video_start();
120120   virtual void video_reset();
r20930r20931
126126   DECLARE_WRITE8_MEMBER(psg_4015_w);
127127   DECLARE_WRITE8_MEMBER(psg_4017_w);
128128   void nes_banks_restore();
129   DECLARE_DEVICE_IMAGE_LOAD_MEMBER(nes_cart);
130129   DECLARE_DEVICE_IMAGE_LOAD_MEMBER(nes_disk);
131130   DECLARE_DEVICE_IMAGE_UNLOAD_MEMBER(nes_disk);
132131
r20930r20931
144143   ioport_port       *m_io_zapper2_y;
145144   ioport_port       *m_io_paddle;
146145
146   optional_device<nes_cart_slot_device> m_cartslot;   //mandatory
147
147148private:
148149   /* devices */
149150//  cpu_device        *m_maincpu;
150151//  ppu2c0x_device    *m_ppu;
151152//  device_t          *m_sound;
152   device_t          *m_cart;
153153//  emu_timer         *m_irq_timer;
154154   memory_bank       *m_prg_bank_mem[5];
155155};
156156
157   
157158/*----------- defined in machine/nes.c -----------*/
158159
159160
trunk/src/mess/includes/nes_mmc.h
r20930r20931
11#ifndef __MMC_H
22#define __MMC_H
33
4#include "video/ppu2c0x.h"
5
46/* Boards */
57enum
68{
r20930r20931
109111
110112// these are used to setup the proper PCB ID, for each supported type of files
111113int nes_get_pcb_id(running_machine &machine, const char *feature);  // for softlist
112void unif_mapr_setup(running_machine &machine, const char *board);  // for UNIF files
114void unif_mapr_setup(const char *board, int *pcb_id, int *battery, int *prgram, int *vram_chunks);   // for UNIF files
113115int nes_get_mmc_id(running_machine &machine, int mapper);   // for iNES files
114116
115117// these are used to setup handlers and callbacks necessary to the emulation (resp. at start and reset)
r20930r20931
610612
611613};
612614
613
614
615615#endif
trunk/src/mess/drivers/nes.c
r20930r20931
1515#include "includes/nes.h"
1616//#include "includes/nes_mmc.h"
1717#include "cpu/m6502/n2a03.h"
18#include "imagedev/cartslot.h"
1918#include "sound/nes_apu.h"
2019#include "imagedev/flopdrv.h"
2120#include "formats/nes_dsk.h"
r20930r20931
5352   AM_RANGE(0x4016, 0x4016) AM_READWRITE(nes_IN0_r, nes_IN0_w)         /* IN0 - input port 1 */
5453   AM_RANGE(0x4017, 0x4017) AM_READ(nes_IN1_r)                         /* IN1 - input port 2 */
5554   AM_RANGE(0x4017, 0x4017) AM_WRITE(psg_4017_w)       /* PSG second control register */
56   AM_RANGE(0x4100, 0x5fff) AM_READWRITE(nes_low_mapper_r, nes_low_mapper_w)   /* Perform unholy acts on the machine */
55   // 0x4100-0x5fff -> LOW HANDLER defined on a pcb base
56   // 0x6000-0x7fff -> MID HANDLER defined on a pcb base
57   // 0x8000-0xffff -> HIGH HANDLER defined on a pcb base
5758ADDRESS_MAP_END
5859
5960
r20930r20931
442443};
443444
444445
446static const nes_cart_interface nes_crt_interface =
447{
448};
449
450static SLOT_INTERFACE_START(nes_cart)
451   SLOT_INTERFACE("rom",  NES_ROM)
452SLOT_INTERFACE_END
453
445454static MACHINE_CONFIG_START( nes, nes_state )
446455   /* basic machine hardware */
447456   MCFG_CPU_ADD("maincpu", N2A03, NTSC_CLOCK)
r20930r20931
470479   MCFG_SOUND_CONFIG(nes_apu_interface)
471480   MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.90)
472481
473   MCFG_CARTSLOT_ADD("cart")
474   MCFG_CARTSLOT_EXTENSION_LIST("nes,unf")
475   MCFG_CARTSLOT_MANDATORY
476   MCFG_CARTSLOT_INTERFACE("nes_cart")
477   MCFG_CARTSLOT_LOAD(nes_state,nes_cart)
478   MCFG_CARTSLOT_PARTIALHASH(nes_partialhash)
482   MCFG_NES_CARTRIDGE_ADD("nes_slot", nes_crt_interface, nes_cart, NULL, NULL)
479483   MCFG_SOFTWARE_LIST_ADD("cart_list","nes")
480484MACHINE_CONFIG_END
481485
r20930r20931
522526MACHINE_CONFIG_END
523527
524528static MACHINE_CONFIG_DERIVED( famicom, nes )
529   MCFG_DEVICE_REMOVE( "nes_slot" )
530//   MCFG_FC_CARTRIDGE_ADD("nes_slot", nes_crt_interface, nes_cart, NULL, NULL)   // here we need a non-mandatory cart...
525531
526   MCFG_CARTSLOT_MODIFY("cart")
527   MCFG_CARTSLOT_EXTENSION_LIST("nes,unf")
528   MCFG_CARTSLOT_NOT_MANDATORY
529   MCFG_CARTSLOT_LOAD(nes_state,nes_cart)
530   MCFG_CARTSLOT_PARTIALHASH(nes_partialhash)
531
532532   MCFG_LEGACY_FLOPPY_DRIVE_ADD(FLOPPY_0, nes_floppy_interface)
533533   MCFG_SOFTWARE_LIST_ADD("flop_list","famicom_flop")
534534MACHINE_CONFIG_END
535535
536//static MACHINE_CONFIG_DERIVED( nes_test, nes )
537//MACHINE_CONFIG_END
538536
539
540537/* rom regions are just place-holders: they get removed and re-allocated when a cart is loaded */
541538ROM_START( nes )
542539   ROM_REGION( 0x10000, "maincpu", ROMREGION_ERASE00 )  /* Main RAM */
r20930r20931
588585   ROM_REGION( 0x800,   "ciram", ROMREGION_ERASE00 )  /* CI RAM */
589586ROM_END
590587
591//#define rom_nes_test rom_nes
592588
593589/***************************************************************************
594590
r20930r20931
604600CONS( 198?, m82,       nes,    0,     nes,      nes, driver_device,     0,       "Nintendo",  "M82 Display Unit", GAME_IMPERFECT_GRAPHICS | GAME_NOT_WORKING )
605601CONS( 1996, drpcjr,    nes,    0,     famicom,  famicom, nes_state, famicom, "Bung",      "Doctor PC Jr", GAME_IMPERFECT_GRAPHICS )
606602CONS( 1992, dendy,     nes,    0,     dendy,    nes, driver_device,     0,       "Steepler",  "Dendy Classic", GAME_IMPERFECT_GRAPHICS )
607
608//CONS( 1985, nes_test,  0,      0,     nes_test, nes, driver_device,     0,       "Nintendo",  "Nintendo Entertainment System (Testdriver)", GAME_IMPERFECT_GRAPHICS )
trunk/src/mess/mess.mak
r20930r20931
14171417
14181418$(MESSOBJ)/nintendo.a:          \
14191419   $(MESS_MACHINE)/nes_mmc.o   \
1420   $(MESS_MACHINE)/nes_slot.o  \
14201421   $(MESS_VIDEO)/nes.o         \
14211422   $(MESS_MACHINE)/nes.o       \
14221423   $(MESS_DRIVERS)/nes.o       \

Previous 199869 Revisions Next


© 1997-2024 The MAME Team