license info at top of Cyclone source files
[cyclone68000.git] / Pico / Cart.cpp
CommitLineData
15eb0001 1\r
2#include "PicoInt.h"\r
3\r
4static 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
23static 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
32static 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
52int 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
80int 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