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;