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