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