3 // Module for loading in the different rom image types (.bin/.smd)
10 #include <sys/types.h>
15 static int load_bin_into(char *name
,unsigned char *into
)
20 hand
=fopen(name
,"rb");
24 fseek(hand
,0,SEEK_END
);
25 file_size
=ftell(hand
);
26 fseek(hand
,0,SEEK_SET
);
27 if (into
==NULL
) return file_size
;
29 fread(into
,1,file_size
,hand
);
35 WHAT YOU FIND IN THE 512 BYTES HEADER:
44 1: This first byte should have the number of 16KB blocks the rom has.
45 The header isn't part of the formula, so this number is:
46 [size of rom-512]/16386
47 If the size is more than 255, the value should be H00.
49 2: This byte indicates if the ROM is a part of a splitted rom series. If
50 the rom is the last part of the series (or isn't a splitted rom at all),
51 this byte should be H00. In other cases should be H40. See "CREATING
52 SPLITTED ROMS" for details on this format.
55 // 16k chunks, even bytes first then odd
57 static int load_smd_into(char *name
,unsigned char *into
)
59 unsigned char head
[512]={0};
61 int chunk_count
=0,file_chunks
=0;
63 unsigned char *chunk_buf
=NULL
;
66 hand
=fopen(name
,"rb");
70 fseek(hand
,0,SEEK_END
);
71 file_size
=ftell(hand
);
72 fseek(hand
,0,SEEK_SET
);
74 if (fread(head
,1,512,hand
)!=512) { fclose(hand
); return -1; }
76 //chunk_count=head[0];
77 // Sometimes header is wrong apparently
79 file_chunks
=((file_size
-512)/16384);
81 chunk_count
=file_chunks
;
83 //if (chunk_count>file_chunks) chunk_count=file_chunks;
85 if (into
==NULL
) return (chunk_count
*16384);
87 chunk_buf
=malloc(16384);
89 {printf ("out of mem\n"); fclose(hand
); return -1;}
91 for (got_to
=0,i
=0; i
<chunk_count
; i
++,got_to
+=16384)
94 // Deinterleave each chunk
95 fread(chunk_buf
,1,16384,hand
);
97 into
[got_to
+(j
<<1)+1]=chunk_buf
[j
];
99 into
[got_to
+(j
<<1)+0]=chunk_buf
[j
+8192];
108 // If 'into' is NULL returns rom size, otherwise expect
109 // 'into' to be a buffer big enough for the rom size
110 // (i.e. pass NULL, malloc, pass pointer, emulate, free pointer)
112 int load_rom_into(char *name
,unsigned char *into
)
114 int format
=0; // bin 0, smd 1
116 unsigned char magicbuf
[10];
118 if (name
==NULL
) return -1;
120 /* Open the file and get the first little shnippit of it so we can check
121 * the magic numbers on it. */
122 if(!(romfile
= fopen(name
, "rb"))) return -1;
123 fread(magicbuf
, 10, 1, romfile
);
126 /* Check for the magic on various gzip-supported compressions */
127 if((magicbuf
[0] == 037 && magicbuf
[1] == 036) || /* compress'd (.Z) */
128 (magicbuf
[0] == 037 && magicbuf
[1] == 0213) || /* gzipped (.gz) */
129 (magicbuf
[0] == 037 && magicbuf
[1] == 0236) || /* frozen (.f,.z) */
130 (magicbuf
[0] == 037 && magicbuf
[1] == 0240) || /* LZH (?) */
131 (magicbuf
[0] == 'P' && magicbuf
[1] == 'K')) /* ZIP (.zip ;) */
133 char temp
[0x100], *temp2
;
135 /* Run it through gzip (I know this is cheap ;) */
136 asprintf(&temp2
, "/tmp/dgenrom_XXXXXX");
144 f
= open(name
, O_RDONLY
);
149 if (dup2(f
, 0) == -1) {
153 sprintf(temp
, "zcat > %s", temp2
);
159 /* Recurse with the new file */
160 len
= load_rom_into(temp2
, into
);
166 if(magicbuf
[0] == 'B' && magicbuf
[1] == 'Z' && magicbuf
[2] == 'h')
168 char temp
[0x100], *temp2
;
170 /* Damn, this looks almost like the gzip stuff above. *lol* :) */
171 asprintf(&temp2
, "/tmp/dgenrom_XXXXXX");
179 f
= open(name
, O_RDONLY
);
184 if (dup2(f
, 0) == -1) {
188 sprintf(temp
, "bzcat > %s", temp2
);
194 /* Recurse with the uncompressed file */
195 len
= load_rom_into(temp2
, into
);
200 /* Next check for SMD magic */
201 if(magicbuf
[8] == 0xaa && magicbuf
[9] == 0xbb)
203 /* Otherwise we can only hope it's binary */
208 case 1: return load_smd_into(name
,into
);
209 default: return load_bin_into(name
,into
);