Previous 199869 Revisions Next

r31772 Monday 25th August, 2014 at 18:48:48 UTC by Fabio Priuli
(MESS) a78_slot: added logging of the A78 header, fixed identification of
some games when loaded from fullpath, and hopefully fixed crash when
loading carts from the internal UI. nw.
[src/emu/bus/a7800]a78_slot.c a78_slot.h xboard.c

trunk/src/emu/bus/a7800/a78_slot.h
r31771r31772
4949   void ram_alloc(UINT32 size);
5050   void nvram_alloc(UINT32 size);
5151   UINT8* get_rom_base() { return m_rom; }
52   UINT8*  get_ram_base() { return m_ram; }
53   UINT8*  get_nvram_base() { return m_nvram; }
54   UINT32  get_rom_size() { return m_rom.bytes(); }
55   UINT32  get_ram_size() { return m_ram.bytes(); }
56   UINT32  get_nvram_size() { return m_nvram.bytes(); }
52   UINT8* get_ram_base() { return m_ram; }
53   UINT8* get_nvram_base() { return m_nvram; }
54   UINT32 get_rom_size() { return m_rom.bytes(); }
55   UINT32 get_ram_size() { return m_ram.bytes(); }
56   UINT32 get_nvram_size() { return m_nvram.bytes(); }
5757
5858protected:
5959   // internal state
r31771r31772
123123   int m_stick_type;
124124
125125   int verify_header(char *header);
126   void internal_header_logging(UINT8 *header, UINT32 len);
126127};
127128
128129
trunk/src/emu/bus/a7800/xboard.c
r31771r31772
3737 
3838 TODO:
3939  - verify what happens when 2 POKEYs are present
40  - verify whether high score works fine with XM
40  - understand why high score in XM is not written to NVRAM
41  - add Yamaha YM2151 when more clear specs are available
4142
4243***********************************************************************************************************/
4344
trunk/src/emu/bus/a7800/a78_slot.c
r31771r31772
3939//-------------------------------------------------
4040
4141device_a78_cart_interface::device_a78_cart_interface (const machine_config &mconfig, device_t &device)
42   : device_slot_card_interface(mconfig, device)
42   : device_slot_card_interface(mconfig, device),
43      m_base_rom(0x8000),
44      m_bank_mask(0)
4345{
4446}
4547
r31771r31772
6062{
6163   if (m_rom == NULL)
6264   {
63      // allocate rom
6465      m_rom.resize(size);
65
66     
6667      // setup other helpers
6768      if ((size / 0x4000) & 1) // compensate for SuperGame carts with 9 x 16K banks (to my knowledge no other cart has m_bank_mask != power of 2)
6869         m_bank_mask = (size / 0x4000) - 2;
6970      else
7071         m_bank_mask = (size / 0x4000) - 1;
71
72     
7273      // the rom is mapped to the top of the memory area
7374      // so we store the starting point of data to simplify
7475      // the access handling
r31771r31772
207208
208209bool a78_cart_slot_device::call_load()
209210{
210   UINT8 *ROM;
211   UINT32 len;
212
213   if (software_entry() != NULL)
211   if (m_cart)
214212   {
215      const char *pcb_name;
216      len = get_software_region_length("rom");
217
218      m_cart->rom_alloc(len);
219      ROM = m_cart->get_rom_base();
220      memcpy(ROM, get_software_region("rom"), len);
221
222      if ((pcb_name = get_feature("slot")) != NULL)
223         m_type = a78_get_pcb_id(pcb_name);
224      else
225         m_type = A78_TYPE0;
226   }
227   else
228   {
229      // Load and check the header
230      char head[128];     
231      fread(head, 128);
213      UINT8 *ROM;
214      UINT32 len;
232215     
233      if (verify_header((char *)head) == IMAGE_VERIFY_FAIL)
234         return IMAGE_INIT_FAIL;
235
236      len = (head[49] << 24) |(head[50] << 16) |(head[51] << 8) | head[52];
237      if (len + 128 > length())
216      if (software_entry() != NULL)
238217      {
239         logerror("Invalid length in the header. The game might be corrupted.\n");
240         len = length() - 128;
218         const char *pcb_name;
219         len = get_software_region_length("rom");
220         
221         m_cart->rom_alloc(len);
222         ROM = m_cart->get_rom_base();
223         memcpy(ROM, get_software_region("rom"), len);
224         
225         if ((pcb_name = get_feature("slot")) != NULL)
226            m_type = a78_get_pcb_id(pcb_name);
227         else
228            m_type = A78_TYPE0;
241229      }
242
243      switch ((head[53] << 8) | head[54])
230      else
244231      {
245         case 0x0000:
246            m_type = A78_TYPE0;
247            break;
248         case 0x0001:
249            m_type = A78_TYPE1;
250            break;
251         case 0x0002:
252            m_type = A78_TYPE2;
253            break;
254         case 0x0003:
255            m_type = A78_TYPE3;
256            break;
257         case 0x0006:
258            m_type = A78_TYPE6;
259            break;
260         case 0x000a:
261            m_type = A78_TYPEA;
262            break;
263         case 0x000b:
264            m_type = A78_TYPEB;
265            break;
266         case 0x0020:
267            m_type = A78_BANKRAM;
268            break;
269         case 0x0100:
270            m_type = A78_ABSOLUTE;
271            break;
272         case 0x0200:
273            m_type = A78_ACTIVISION;
274            break;
232         // Load and check the header
233         char head[128];     
234         fread(head, 128);
235         
236         if (verify_header((char *)head) == IMAGE_VERIFY_FAIL)
237            return IMAGE_INIT_FAIL;
238         
239         len = (head[49] << 24) | (head[50] << 16) | (head[51] << 8) | head[52];
240         if (len + 128 > length())
241         {
242            logerror("Invalid length in the header. The game might be corrupted.\n");
243            len = length() - 128;
244         }
245         
246         switch ((head[53] << 8) | head[54])
247         {
248            case 0x0000:
249               m_type = A78_TYPE0;
250               break;
251            case 0x0001:
252               m_type = A78_TYPE1;
253               break;
254            case 0x0002:
255               m_type = A78_TYPE2;
256               break;
257            case 0x0003:
258               m_type = A78_TYPE3;
259               break;
260            case 0x0006:
261               m_type = A78_TYPE6;
262               break;
263            case 0x000a:
264               m_type = A78_TYPEA;
265               break;
266            case 0x000b:
267               m_type = A78_TYPEB;
268               break;
269            case 0x0020:
270               m_type = A78_BANKRAM;
271               break;
272            case 0x0100:
273               m_type = A78_ABSOLUTE;
274               break;
275            case 0x0200:
276               m_type = A78_ACTIVISION;
277               break;
278         }
279         logerror("Cart type: %x\n", m_type);
280         
281         internal_header_logging((UINT8 *)head, length());
282         
283         m_cart->rom_alloc(len);
284         ROM = m_cart->get_rom_base();
285         fread(ROM, len);
275286      }
276      logerror("Cart type: %x\n", m_type);
277287     
278      // This field is currently only used for logging
279      m_stick_type = head[55];
288      //printf("Type: %s\n", a78_get_slot(m_type));
280289     
281      m_cart->rom_alloc(len);
282      ROM = m_cart->get_rom_base();
283      fread(ROM, len);
290      if (m_type == A78_TYPE6)
291         m_cart->ram_alloc(0x4000);
292      if (m_type == A78_BANKRAM)
293         m_cart->ram_alloc(0x8000);
294      if (m_type == A78_XB_BOARD || m_type == A78_XM_BOARD)
295         m_cart->ram_alloc(0x20000);
296      if (m_type == A78_HSC || m_type == A78_XM_BOARD)
297      {
298         m_cart->nvram_alloc(0x800);
299         battery_load(m_cart->get_nvram_base(), 0x800, 0xff);
300      }
284301   }
285
286   //printf("Type: %s\n", a78_get_slot(m_type));
287
288   if (m_type == A78_TYPE6)
289      m_cart->ram_alloc(0x4000);
290   if (m_type == A78_BANKRAM)
291      m_cart->ram_alloc(0x8000);
292   if (m_type == A78_XB_BOARD || m_type == A78_XM_BOARD)
293      m_cart->ram_alloc(0x20000);
294   if (m_type == A78_HSC || m_type == A78_XM_BOARD)
295   {
296      m_cart->nvram_alloc(0x800);
297      battery_load(m_cart->get_nvram_base(), 0x800, 0xff);
298   }
299
300302   return IMAGE_INIT_PASS;
301303}
302304
r31771r31772
380382         case 0x0003:
381383            type = A78_TYPE3;
382384            break;
383         case 0x0004:
385         case 0x0006:
384386            type = A78_TYPE6;
385387            break;
386388         case 0x000a:
r31771r31772
477479}
478480
479481
480/*  Header format
481 0     Header version     - 1 byte
482 1..16  "ATARI7800     "  - 16 bytes
483 17..48 Cart title        - 32 bytes
484 49..52 data length      - 4 bytes
485 53..54 cart type          - 2 bytes
486 bit 0 0x01 - pokey cart
487 bit 1 0x02 - supercart bank switched
488 bit 2 0x04 - supercart RAM at $4000
489 bit 3 0x08 - additional ROM at $4000
490 bit 4 0x10 - bank 6 at $4000
491 bit 5 0x20 - supercart banked RAM
492 
493 bit 8-15 - Special
494 0 = Normal cart
495 1 = Absolute (F18 Hornet)
496 2 = Activision
497 
498 55   controller 1 type  - 1 byte
499 56   controller 2 type  - 1 byte
500 0 = None
501 1 = Joystick
502 2 = Light Gun
503 57  0 = NTSC/1 = PAL
504 
505 100..127 "ACTUAL CART DATA STARTS HERE" - 28 bytes
506 
507 Versions:
508 Version 0: Initial release
509 Version 1: Added PAL/NTSC bit. Added Special cart byte.
510 Changed 53 bit 2, added bit 3
511 
512 */
482/*-------------------------------------------------
483 A78 header logging
484 -------------------------------------------------*/
513485
514// TODO: log all properties from the header
No newline at end of file
486void a78_cart_slot_device::internal_header_logging(UINT8 *header, UINT32 len)
487{
488   char head_title[35];
489   UINT32 head_length = (header[49] << 24) | (header[50] << 16) | (header[51] << 8) | header[52];
490   UINT16 head_mapper = (header[53] << 8) | header[54];
491   UINT8 head_ctrl1 = header[55];
492   UINT8 head_ctrl2 = header[56];
493   UINT8 head_ispal = header[57];
494   astring cart_mapper, ctrl1, ctrl2;
495   memcpy(head_title, header + 0x11, 0x20);
496
497   switch (head_mapper)
498   {
499      case 0x0000:
500         cart_mapper.cpy("No Bankswitch");
501         break;
502      case 0x0001:
503         cart_mapper.cpy("No Bankswitch + POKEY");
504         break;
505      case 0x0002:
506         cart_mapper.cpy("SuperCart Bankswitch");
507         break;
508      case 0x0003:
509         cart_mapper.cpy("SuperCart Bankswitch + POKEY");
510         break;
511      case 0x0006:
512         cart_mapper.cpy("SuperCart Bankswitch + RAM");
513         break;
514      case 0x000a:
515         cart_mapper.cpy("SuperCart 9Banks");
516         break;
517      case 0x000b:
518         cart_mapper.cpy("SuperCart XM Compatible");
519         break;
520      case 0x0020:
521         cart_mapper.cpy("SuperCart Bankswitch + 32K RAM");
522         break;
523      case 0x0100:
524         cart_mapper.cpy("Absolute Bankswitch");
525         break;
526      case 0x0200:
527         cart_mapper.cpy("Activision Bankswitch");
528         break;
529      default:
530         cart_mapper.cpy("Unknown mapper");
531         break;
532   }
533
534   switch (head_ctrl1)
535   {
536      case 0x00:
537         ctrl1.cpy("None");
538         break;
539      case 0x01:
540         ctrl1.cpy("Joystick");
541         break;
542      case 0x02:
543         ctrl1.cpy("Light Gun");
544         break;
545      default:
546         ctrl1.cpy("Unknown controller");
547         break;
548   }
549   
550   switch (head_ctrl2)
551   {
552      case 0x00:
553         ctrl2.cpy("None");
554         break;
555      case 0x01:
556         ctrl2.cpy("Joystick");
557         break;
558      case 0x02:
559         ctrl2.cpy("Light Gun");
560         break;
561      default:
562         ctrl2.cpy("Unknown controller");
563         break;
564   }
565   
566   logerror( "ROM DETAILS\n" );
567   logerror( "===========\n\n" );
568   logerror( "\tTotal length (with header):  0x%x (%dK + 128b header)\n\nn", len, len/0x400);   
569   logerror( "HEADER DETAILS\n" );
570   logerror( "==============\n\n" );
571   logerror( "\tTitle:           %.32s\n", head_title);
572   logerror( "\tLength:          0x%X [real 0x%X]\n", head_length, len);
573   logerror( "\tMapper:          %s\n", cart_mapper.cstr());
574   logerror( "\t\tPOKEY:           %s\n", BIT(head_mapper, 0) ? "Yes" : "No");
575   logerror( "\t\tSC Bankswitch:   %s\n", BIT(head_mapper, 1) ? "Yes" : "No");
576   logerror( "\t\tRAM at $4000:    %s\n", BIT(head_mapper, 2) ? "Yes" : "No");
577   logerror( "\t\tbank0 at $4000:  %s\n", BIT(head_mapper, 3) ? "Yes" : "No");
578   logerror( "\t\tbank6 at $4000:  %s\n", BIT(head_mapper, 4) ? "Yes" : "No");
579   logerror( "\t\tbanked RAM:      %s\n", BIT(head_mapper, 5) ? "Yes" : "No");
580   logerror( "\t\tSpecial:         %s ", (head_mapper & 0xff00) ? "Yes" : "No");
581   if (head_mapper & 0xff00)
582   {
583      logerror( "[%s]\n", (head_mapper & 0xff00) == 0x100 ? "Absolute" :
584                        (head_mapper & 0xff00) == 0x200 ? "Activision" : "Unknown" );
585   }
586   else
587      logerror( "\n");
588   logerror( "\tController 1:    0x%.2X [%s]\n", head_ctrl1, ctrl1.cstr());
589   logerror( "\tController 2:    0x%.2X [%s]\n", head_ctrl2, ctrl2.cstr());
590   logerror( "\tVideo:           %s\n", (head_ispal) ? "PAL" : "NTSC");   
591}

Previous 199869 Revisions Next


© 1997-2024 The MAME Team