Mercurial > repos > blastem
comparison cdd_mcu.c @ 2065:02a9846668d1 segacd
Implement transfer of data from CDC to elsewhere. Other miscellaneous CDD/CDC improvements
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Sat, 29 Jan 2022 17:43:37 -0800 |
parents | 91e4d2fe5cd9 |
children | f22e04b69272 |
comparison
equal
deleted
inserted
replaced
2064:91e4d2fe5cd9 | 2065:02a9846668d1 |
---|---|
151 } | 151 } |
152 if (context->first_cmd_received) { | 152 if (context->first_cmd_received) { |
153 switch (context->requested_format) | 153 switch (context->requested_format) |
154 { | 154 { |
155 case SF_ABSOLUTE: | 155 case SF_ABSOLUTE: |
156 if (context->toc_valid) { | 156 if (context->toc_valid && context->head_pba >= LEADIN_SECTORS) { |
157 lba_to_status(context, context->head_pba - LEADIN_SECTORS); | 157 lba_to_status(context, context->head_pba - LEADIN_SECTORS); |
158 context->status_buffer.format = SF_ABSOLUTE; | 158 context->status_buffer.format = SF_ABSOLUTE; |
159 } else { | 159 } else { |
160 context->status_buffer.format = SF_NOTREADY; | 160 context->status_buffer.format = SF_NOTREADY; |
161 } | 161 } |
162 break; | 162 break; |
163 case SF_RELATIVE: | 163 case SF_RELATIVE: |
164 if (context->toc_valid) { | 164 if (context->toc_valid && context->head_pba >= LEADIN_SECTORS) { |
165 uint32_t lba =context->head_pba - LEADIN_SECTORS; | 165 uint32_t lba =context->head_pba - LEADIN_SECTORS; |
166 for (uint32_t i = 0; i < context->media->num_tracks; i++) | 166 for (uint32_t i = 0; i < context->media->num_tracks; i++) |
167 { | 167 { |
168 if (lba < context->media->tracks[i].end_lba) { | 168 if (lba < context->media->tracks[i].end_lba) { |
169 if (context->media->tracks[i].fake_pregap) { | 169 if (context->media->tracks[i].fake_pregap) { |
185 } else if (context->media->tracks[i].fake_pregap) { | 185 } else if (context->media->tracks[i].fake_pregap) { |
186 lba -= context->media->tracks[i].fake_pregap; | 186 lba -= context->media->tracks[i].fake_pregap; |
187 } | 187 } |
188 } | 188 } |
189 lba_to_status(context, lba); | 189 lba_to_status(context, lba); |
190 context->status_buffer.format = SF_ABSOLUTE; | 190 context->status_buffer.format = SF_RELATIVE; |
191 } else { | |
192 context->status_buffer.format = SF_NOTREADY; | |
193 } | |
194 break; | |
195 case SF_TRACK: | |
196 if (context->toc_valid && context->head_pba >= LEADIN_SECTORS) { | |
197 uint32_t lba =context->head_pba - LEADIN_SECTORS; | |
198 uint32_t i; | |
199 for (i = 0; i < context->media->num_tracks; i++) | |
200 { | |
201 if (lba < context->media->tracks[i].end_lba) { | |
202 if (context->media->tracks[i].fake_pregap) { | |
203 if (lba > context->media->tracks[i].fake_pregap) { | |
204 lba -= context->media->tracks[i].fake_pregap; | |
205 } else { | |
206 //relative time counts down to 0 in pregap | |
207 lba = context->media->tracks[i].fake_pregap - lba; | |
208 break; | |
209 } | |
210 } | |
211 if (lba < context->media->tracks[i].start_lba) { | |
212 //relative time counts down to 0 in pregap | |
213 lba = context->media->tracks[i].start_lba - lba; | |
214 } else { | |
215 lba -= context->media->tracks[i].start_lba; | |
216 } | |
217 break; | |
218 } else if (context->media->tracks[i].fake_pregap) { | |
219 lba -= context->media->tracks[i].fake_pregap; | |
220 } | |
221 } | |
222 context->status_buffer.b.track.track_high = (i + 1) / 10; | |
223 context->status_buffer.b.track.track_low = (i + 1) % 10; | |
224 if (context->media->tracks[i].type == TRACK_DATA) { | |
225 context->status_buffer.b.track.control = 4; | |
226 } else { | |
227 //TODO: pre-emphasis flag | |
228 //TODO: copy permitted flag | |
229 context->status_buffer.b.track.control = 0; | |
230 } | |
231 context->status_buffer.b.track.adr = 1; | |
232 context->status_buffer.format = SF_TRACK; | |
191 } else { | 233 } else { |
192 context->status_buffer.format = SF_NOTREADY; | 234 context->status_buffer.format = SF_NOTREADY; |
193 } | 235 } |
194 break; | 236 break; |
195 case SF_TOCO: | 237 case SF_TOCO: |
218 } | 260 } |
219 break; | 261 break; |
220 case SF_TOCN: | 262 case SF_TOCN: |
221 if (context->toc_valid) { | 263 if (context->toc_valid) { |
222 uint32_t lba = context->media->tracks[context->requested_track - 1].start_lba; | 264 uint32_t lba = context->media->tracks[context->requested_track - 1].start_lba; |
223 if (context->requested_track > 1) { | 265 for (uint32_t i = 0; i < context->requested_track; i++) { |
224 lba += context->media->tracks[1].fake_pregap; | 266 lba += context->media->tracks[i].fake_pregap; |
225 } | 267 } |
226 lba_to_status(context, lba); | 268 lba_to_status(context, lba); |
269 if (context->media->tracks[context->requested_track - 1].type == TRACK_DATA) { | |
270 context->status_buffer.b.tocn.frame_low |= 0x80; | |
271 } | |
227 context->status_buffer.b.tocn.track_low = context->requested_track % 10; | 272 context->status_buffer.b.tocn.track_low = context->requested_track % 10; |
228 context->status_buffer.format = SF_TOCN; | 273 context->status_buffer.format = SF_TOCN; |
229 } else { | 274 } else { |
230 context->status_buffer.format = SF_NOTREADY; | 275 context->status_buffer.format = SF_NOTREADY; |
231 } | 276 } |
236 break; | 281 break; |
237 } | 282 } |
238 if (context->error_status == DS_STOP) { | 283 if (context->error_status == DS_STOP) { |
239 if (context->requested_format >= SF_TOCO && context->requested_format <= SF_TOCN) { | 284 if (context->requested_format >= SF_TOCO && context->requested_format <= SF_TOCN) { |
240 context->status_buffer.status = DS_TOC_READ; | 285 context->status_buffer.status = DS_TOC_READ; |
286 } else if (context->seeking) { | |
287 context->status_buffer.status = DS_SEEK; | |
241 } else { | 288 } else { |
242 context->status_buffer.status = context->status; | 289 context->status_buffer.status = context->status; |
243 } | 290 } |
244 } else { | 291 } else { |
245 context->status_buffer.status = context->error_status; | 292 context->status_buffer.status = context->error_status; |
303 uint32_t lba = context->cmd_buffer.b.time.min_high * 10 + context->cmd_buffer.b.time.min_low; | 350 uint32_t lba = context->cmd_buffer.b.time.min_high * 10 + context->cmd_buffer.b.time.min_low; |
304 lba *= 60; | 351 lba *= 60; |
305 lba += context->cmd_buffer.b.time.sec_high * 10 + context->cmd_buffer.b.time.sec_low; | 352 lba += context->cmd_buffer.b.time.sec_high * 10 + context->cmd_buffer.b.time.sec_low; |
306 lba *= 75; | 353 lba *= 75; |
307 lba += context->cmd_buffer.b.time.frame_high * 10 + context->cmd_buffer.b.time.frame_low; | 354 lba += context->cmd_buffer.b.time.frame_high * 10 + context->cmd_buffer.b.time.frame_low; |
308 printf("READ/SEEK cmd for lba %d\n", lba); | 355 printf("READ/SEEK cmd for lba %d, MM:SS:FF %u%u:%u%u:%u%u\n", lba, |
356 context->cmd_buffer.b.time.min_high, context->cmd_buffer.b.time.min_low, | |
357 context->cmd_buffer.b.time.sec_high, context->cmd_buffer.b.time.sec_low, | |
358 context->cmd_buffer.b.time.frame_high, context->cmd_buffer.b.time.frame_low | |
359 ); | |
309 if (lba >= context->media->tracks[0].fake_pregap + context->media->tracks[context->media->num_tracks - 1].end_lba) { | 360 if (lba >= context->media->tracks[0].fake_pregap + context->media->tracks[context->media->num_tracks - 1].end_lba) { |
310 context->error_status = DS_CMD_ERROR; | 361 context->error_status = DS_CMD_ERROR; |
311 break; | 362 break; |
312 } | 363 } |
313 context->seek_pba = lba + LEADIN_SECTORS - 4; | 364 context->seek_pba = lba + LEADIN_SECTORS - 4; |