comparison blastem.c @ 1683:7e044a84268d

Add support for SMD format ROMs in ZIP files
author Michael Pavone <pavone@retrodev.com>
date Thu, 17 Jan 2019 23:55:49 -0800
parents a0aa9e3c9508
children f6bd4962b8f5
comparison
equal deleted inserted replaced
1682:a0aa9e3c9508 1683:7e044a84268d
67 #define romseek gzseek 67 #define romseek gzseek
68 #define romgetc gzgetc 68 #define romgetc gzgetc
69 #define romclose gzclose 69 #define romclose gzclose
70 #endif 70 #endif
71 71
72 uint16_t *process_smd_block(uint16_t *dst, uint8_t *src, size_t bytes)
73 {
74 for (uint8_t *low = src, *high = (src+bytes/2), *end = src+bytes; high < end; high++, low++) {
75 *(dst++) = *low << 8 | *high;
76 }
77 return dst;
78 }
79
72 int load_smd_rom(ROMFILE f, void **buffer) 80 int load_smd_rom(ROMFILE f, void **buffer)
73 { 81 {
74 uint8_t block[SMD_BLOCK_SIZE]; 82 uint8_t block[SMD_BLOCK_SIZE];
75 romseek(f, SMD_HEADER_SIZE, SEEK_SET); 83 romseek(f, SMD_HEADER_SIZE, SEEK_SET);
76 84
87 buf = realloc(buf, filesize); 95 buf = realloc(buf, filesize);
88 dst = buf + readsize/sizeof(uint16_t); 96 dst = buf + readsize/sizeof(uint16_t);
89 } 97 }
90 read = romread(block, 1, SMD_BLOCK_SIZE, f); 98 read = romread(block, 1, SMD_BLOCK_SIZE, f);
91 if (read > 0) { 99 if (read > 0) {
92 for (uint8_t *low = block, *high = (block+read/2), *end = block+read; high < end; high++, low++) { 100 dst = process_smd_block(dst, block, read);
93 *(dst++) = *low << 8 | *high;
94 }
95 readsize += read; 101 readsize += read;
96 } 102 }
97 } while(read > 0); 103 } while(read > 0);
98 romclose(f); 104 romclose(f);
99 105
100 *buffer = buf; 106 *buffer = buf;
101 107
102 return readsize; 108 return readsize;
103 } 109 }
104 110
111 uint8_t is_smd_format(const char *filename, uint8_t *header)
112 {
113 if (header[1] == SMD_MAGIC1 && header[8] == SMD_MAGIC2 && header[9] == SMD_MAGIC3) {
114 int i;
115 for (i = 3; i < 8; i++) {
116 if (header[i] != 0) {
117 return 0;
118 }
119 }
120 if (i == 8) {
121 if (header[2]) {
122 fatal_error("%s is a split SMD ROM which is not currently supported", filename);
123 }
124 return 1;
125 }
126 }
127 return 0;
128 }
129
105 uint32_t load_rom_zip(const char *filename, void **dst) 130 uint32_t load_rom_zip(const char *filename, void **dst)
106 { 131 {
107 static const char *valid_exts[] = {"bin", "md", "gen", "sms", "rom"}; 132 static const char *valid_exts[] = {"bin", "md", "gen", "sms", "rom", "smd"};
108 const uint32_t num_exts = sizeof(valid_exts)/sizeof(*valid_exts); 133 const uint32_t num_exts = sizeof(valid_exts)/sizeof(*valid_exts);
109 zip_file *z = zip_open(filename); 134 zip_file *z = zip_open(filename);
110 if (!z) { 135 if (!z) {
111 return 0; 136 return 0;
112 } 137 }
121 { 146 {
122 if (!strcasecmp(ext, valid_exts[j])) { 147 if (!strcasecmp(ext, valid_exts[j])) {
123 size_t out_size = nearest_pow2(z->entries[i].size); 148 size_t out_size = nearest_pow2(z->entries[i].size);
124 *dst = zip_read(z, i, &out_size); 149 *dst = zip_read(z, i, &out_size);
125 if (*dst) { 150 if (*dst) {
151 if (is_smd_format(z->entries[i].name, *dst)) {
152 size_t offset;
153 for (offset = 0; offset + SMD_BLOCK_SIZE + SMD_HEADER_SIZE < out_size; offset += SMD_BLOCK_SIZE)
154 {
155 uint8_t tmp[SMD_BLOCK_SIZE];
156 memcpy(tmp, *dst + offset + SMD_HEADER_SIZE, SMD_BLOCK_SIZE);
157 process_smd_block(*dst + offset, tmp, SMD_BLOCK_SIZE);
158 }
159 out_size = offset;
160 }
126 free(ext); 161 free(ext);
127 zip_close(z); 162 zip_close(z);
128 return out_size; 163 return out_size;
129 } 164 }
130 } 165 }
150 } 185 }
151 if (sizeof(header) != romread(header, 1, sizeof(header), f)) { 186 if (sizeof(header) != romread(header, 1, sizeof(header), f)) {
152 fatal_error("Error reading from %s\n", filename); 187 fatal_error("Error reading from %s\n", filename);
153 } 188 }
154 189
155 if (header[1] == SMD_MAGIC1 && header[8] == SMD_MAGIC2 && header[9] == SMD_MAGIC3) { 190 if (is_smd_format(filename, header)) {
156 int i; 191 if (stype) {
157 for (i = 3; i < 8; i++) { 192 *stype = SYSTEM_GENESIS;
158 if (header[i] != 0) { 193 }
159 break; 194 return load_smd_rom(f, dst);
160 }
161 }
162 if (i == 8) {
163 if (header[2]) {
164 fatal_error("%s is a split SMD ROM which is not currently supported", filename);
165 }
166 if (stype) {
167 *stype = SYSTEM_GENESIS;
168 }
169 return load_smd_rom(f, dst);
170 }
171 } 195 }
172 196
173 size_t filesize = 512 * 1024; 197 size_t filesize = 512 * 1024;
174 size_t readsize = sizeof(header); 198 size_t readsize = sizeof(header);
175 199