comparison cue.c @ 2076:3f29e2726522

Added basic support for ISO images for games that only have a data track
author Michael Pavone <pavone@retrodev.com>
date Mon, 31 Jan 2022 22:07:18 -0800
parents c5323c02dde4
children 5a2b759f6b2d
comparison
equal deleted inserted replaced
2075:983f57d08eff 2076:3f29e2726522
39 } 39 }
40 } 40 }
41 seconds += minutes * 60; 41 seconds += minutes * 60;
42 return seconds * 75 + frames; 42 return seconds * 75 + frames;
43 43
44 }
45
46 static void bin_seek(system_media *media, uint32_t sector)
47 {
48 media->cur_sector = sector;
49 uint32_t lba = sector;
50 for (uint32_t i = 0; i < media->num_tracks; i++)
51 {
52 if (lba < media->tracks[i].fake_pregap) {
53 media->in_fake_pregap = 1;
54 break;
55 }
56 lba -= media->tracks[i].fake_pregap;
57 if (lba < media->tracks[i].start_lba) {
58 media->in_fake_pregap = 1;
59 break;
60 }
61 if (lba < media->tracks[i].end_lba) {
62 media->in_fake_pregap = 0;
63 break;
64 }
65 }
66 if (!media->in_fake_pregap) {
67 fseek(media->f, lba * 2352, SEEK_SET);
68 }
69 }
70
71 static uint8_t fake_read(uint32_t sector, uint32_t offset)
72 {
73 if (!offset || (offset >= 16)) {
74 return 0;
75 //TODO: error detection and correction bytes
76 } else if (offset < 12) {
77 return 0xFF;
78 } else if (offset == 12) {
79 uint32_t minute = (sector / 75) / 60;
80 return (minute % 10) | ((minute / 10 ) << 4);
81 } else if (offset == 13) {
82 uint32_t seconds = (sector / 75) % 60;
83 return (seconds % 10) | ((seconds / 10 ) << 4);
84 } else if (offset == 14) {
85 uint32_t frames = sector % 75;
86 return (frames % 10) | ((frames / 10 ) << 4);
87 } else {
88 return 1;
89 }
90 }
91
92 static uint8_t bin_read(system_media *media, uint32_t offset)
93 {
94 if (media->in_fake_pregap) {
95 return fake_read(media->cur_sector, offset);
96 } else {
97 return fgetc(media->f);
98 }
99 }
100
101 static void iso_seek(system_media *media, uint32_t sector)
102 {
103 media->cur_sector = sector;
104 if (sector < (2 * 75)) {
105 media->in_fake_pregap = 1;
106 } else {
107 media->in_fake_pregap = 0;
108 fseek(media->f, (sector - 2 * 75) * 2048, SEEK_SET);
109 }
110 }
111
112 static uint8_t iso_read(system_media *media, uint32_t offset)
113 {
114 if (media->in_fake_pregap || offset < 16 || offset > (2048 + 16)) {
115 return fake_read(media->cur_sector, offset);
116 } else {
117 return fgetc(media->f);
118 }
44 } 119 }
45 120
46 uint8_t parse_cue(system_media *media) 121 uint8_t parse_cue(system_media *media)
47 { 122 {
48 char *line = media->buffer; 123 char *line = media->buffer;
151 } 226 }
152 } 227 }
153 228
154 fseek(media->f, 16, SEEK_SET); 229 fseek(media->f, 16, SEEK_SET);
155 media->size = fread(media->buffer, 1, 2048, media->f); 230 media->size = fread(media->buffer, 1, 2048, media->f);
231 media->seek = bin_seek;
232 media->read = bin_read;
156 } 233 }
157 uint8_t valid = tracks > 0 && media->f != NULL; 234 uint8_t valid = tracks > 0 && media->f != NULL;
158 media->type = valid ? MEDIA_CDROM : MEDIA_CART; 235 media->type = valid ? MEDIA_CDROM : MEDIA_CART;
159 return valid; 236 return valid;
160 } 237 }
238
239 uint32_t make_iso_media(system_media *media, const char *filename)
240 {
241 media->f = fopen(filename, "rb");
242 if (!media->f) {
243 return 0;
244 }
245 media->buffer = calloc(2048, 1);
246 media->size = fread(media->buffer, 1, 2048, media->f);
247 media->num_tracks = 2;
248 media->tracks = calloc(sizeof(track_info), 2);
249 media->tracks[0] = (track_info){
250 .fake_pregap = 2 * 75,
251 .start_lba = 0,
252 .end_lba = file_size(media->f),
253 .type = TRACK_DATA
254 };
255 media->tracks[1] = (track_info){
256 .fake_pregap = 2 * 75,
257 .start_lba = media->tracks[0].end_lba,
258 .end_lba = media->tracks[0].end_lba + 2 * 75,
259 .type = TRACK_DATA
260 };
261 media->type = MEDIA_CDROM;
262 media->seek = iso_seek;
263 media->read = iso_read;
264 return media->size;
265 }