af79340f0a3046ca1b53179cd7c749c7b3b75057
[cyclone68000.git] / Pico / Cart.cpp
1 \r
2 // This file is part of the PicoDrive Megadrive Emulator\r
3 \r
4 // This code is licensed under the GNU General Public License version 2.0 and the MAME License.\r
5 // You can choose the license that has the most advantages for you.\r
6 \r
7 // SVN repository can be found at http://code.google.com/p/cyclone68000/\r
8 \r
9 #include "PicoInt.h"\r
10 \r
11 static void Byteswap(unsigned char *data,int len)\r
12 {\r
13   int i=0;\r
14 \r
15   if (len<2) return; // Too short\r
16 \r
17   do\r
18   {\r
19     unsigned short *pd=(unsigned short *)(data+i);\r
20     int value=*pd; // Get 2 bytes\r
21 \r
22     value=(value<<8)|(value>>8); // Byteswap it\r
23     *pd=(unsigned short)value; // Put 2b ytes\r
24     i+=2;\r
25   }  \r
26   while (i+2<=len);\r
27 }\r
28 \r
29 // Interleve a 16k block and byteswap\r
30 static int InterleveBlock(unsigned char *dest,unsigned char *src)\r
31 {\r
32   int i=0;\r
33   for (i=0;i<0x2000;i++) dest[(i<<1)  ]=src[       i]; // Odd\r
34   for (i=0;i<0x2000;i++) dest[(i<<1)+1]=src[0x2000+i]; // Even\r
35   return 0;\r
36 }\r
37 \r
38 // Decode a SMD file\r
39 static int DecodeSmd(unsigned char *data,int len)\r
40 {\r
41   unsigned char *temp=NULL;\r
42   int i=0;\r
43 \r
44   temp=(unsigned char *)malloc(0x4000);\r
45   if (temp==NULL) return 1;\r
46   memset(temp,0,0x4000);\r
47 \r
48   // Interleve each 16k block and shift down by 0x200:\r
49   for (i=0; i+0x4200<=len; i+=0x4000)\r
50   {\r
51     InterleveBlock(temp,data+0x200+i); // Interleve 16k to temporary buffer\r
52     memcpy(data+i,temp,0x4000); // Copy back in\r
53   }\r
54 \r
55   free(temp);\r
56   return 0;\r
57 }\r
58 \r
59 int PicoCartLoad(FILE *f,unsigned char **prom,unsigned int *psize)\r
60 {\r
61   unsigned char *rom=NULL; int size=0;\r
62   if (f==NULL) return 1;\r
63 \r
64   fseek(f,0,SEEK_END); size=ftell(f); fseek(f,0,SEEK_SET);\r
65 \r
66   size=(size+3)&~3; // Round up to a multiple of 4\r
67 \r
68   // Allocate space for the rom plus padding\r
69   rom=(unsigned char *)malloc(size+4);\r
70   if (rom==NULL) { fclose(f); return 1; }\r
71   memset(rom,0,size+4);\r
72 \r
73   fread(rom,1,size,f); // Load up the rom\r
74   fclose(f);\r
75 \r
76   // Check for SMD:\r
77   if ((size&0x3fff)==0x200) { DecodeSmd(rom,size); size-=0x200; } // Decode and byteswap SMD\r
78   else Byteswap(rom,size); // Just byteswap\r
79   \r
80   if (prom)  *prom=rom;\r
81   if (psize) *psize=size;\r
82 \r
83   return 0;\r
84 }\r
85 \r
86 // Insert/remove a cartridge:\r
87 int PicoCartInsert(unsigned char *rom,unsigned int romsize)\r
88 {\r
89   // Make sure movie playing/recording is stopped:\r
90   if (PmovFile) fclose(PmovFile);\r
91   PmovFile=NULL; PmovAction=0;\r
92 \r
93   memset(&Pico,0,sizeof(Pico)); // Blank Pico state\r
94   Pico.rom=rom;\r
95   Pico.romsize=romsize;\r
96   PicoReset();\r
97 \r
98   return 0;\r
99 }\r