1 /***************************************************************************
2
3 machine/stvcd.c
4
5 -- we should adapt this to use the .cue / .bin or whatever format we
6 decide to keep the cd in once we have one
7
8 since sports fishing 2 is the only st-v game to require the cd, is an
9 incomplete dump, and will also require the mpeg decoder it seems fairly
10 unlikely this will be done soon
11
12 ***************************************************************************/
13
14 #include "driver.h"
15 #include "machine/stvcd.h"
16 #include <stdio.h>
17
18 UINT8 CD_cr_first;
19 UINT8 CD_cr_writing;
20 UINT16 CR1;
21 UINT16 CR2;
22 UINT16 CR3;
23 UINT16 CR4;
24 UINT16 CD_hirq;
25 UINT16 CD_hirq_i;
26 UINT16 CD_mask;
27 UINT8 CD_status;
28 UINT32 CD_fad;
29 UINT8 CD_track;
30 UINT8 CD_control;
31 UINT8 CD_index;
32
33 UINT32 fn;
34
35 INT32 CD_com; /* last command being processed*/
36 INT32 CD_com_play; /* last play command*/
37 UINT8 CD_stat; /* drive status*/
38 UINT8 CD_flag; /* 0x00 = CD-DA or <SEEK> or <SCAN> 0x80 = CD-ROM*/
39
40
41 UINT32 CD_last_part; /* last buffer partition accessed*/
42 filt_t CD_filt[CDB_SEL_NUM]; /* filters*/
43
44 UINT32 CD_play_fad; /* play start address*/
45 UINT32 CD_play_range; /* play range*/
46 UINT32 CD_seek_target; /* seek target address*/
47 UINT8 CD_scan_dir; /* scan direction*/
48 UINT32 CD_search_pn; /* search result, partition number*/
49 UINT32 CD_search_sp; /* search result, sector position*/
50 UINT32 CD_search_fad; /* search result, fad*/
51 UINT32 CD_file_scope_first;
52 UINT32 CD_file_scope_last;
53
54
55 UINT32 CD_data_pn; /* data transfer partition number*/
56 UINT32 CD_data_sp; /* data transfer sector position*/
57 UINT32 CD_data_sn; /* data transfer sector number*/
58 UINT32 CD_data_count; /* data transfer current byte count*/
59 UINT32 CD_data_delete; /* data must be deleted upon read*/
60 UINT32 CD_data_size; /* data transfer size in bytes*/
61
62 char * CD_info_ptr; /* info transfer buffer pointer*/
63 UINT32 CD_info_count; /* info transfer byte count*/
64 UINT32 CD_info_size; /* info transfer total byte count*/
65
66 UINT32 CD_trans_type; /* 0 = DATA, 1 = INFO */ /*maybe signed int*/
67
68 UINT32 CD_actual_size; /* used by "calcactualsize" and "getactualsize"*/
69
70 /******************************************************************/
71
72 sect_t CD_sect[CDB_SECT_NUM]; /* sector buffer*/
73 part_t CD_part[CDB_SEL_NUM]; /* buffer partitions*/
74 filt_t CD_filt[CDB_SEL_NUM]; /* filters*/
75 UINT32 CD_free_space; /* free space in sector units*/
76
77 UINT8 CD_filt_num; /* cdrom drive connector*/
78 UINT8 CD_mpeg_filt_num; /* mpeg connector*/
79
80 /******************************************************************/
81
82
83 UINT32 CD_cur_fad; /* current pickup position info*/
84 UINT32 CD_cur_track; /**/
85 UINT32 CD_cur_ctrl; /**/
86 UINT32 CD_cur_idx; /**/
87 UINT32 CD_cur_fid; /**/
88
89
90
91 char cdb_sat_file_info[254 * 12]; /* current file info*/
92 char cdb_sat_subq[5 * 2]; /* current subcode q*/
93 char cdb_sat_subrw[12 * 2]; /* current subcode r~w*/
94 char CD_sat_subq[5 * 2]; /* current subcode q*/
95 char CD_sat_subrw[12 * 2]; /* current subcode r~w*/
96 toc_t CD_toc; /* disc toc*/
97 file_t CD_file[CDB_FID_NUM]; /* file table (directory table)*/
98 UINT32 CD_file_num; /* total file infos stored*/
99 char CD_sat_toc[408]; /* current cdrom toc*/
100
101
102 UINT8 CD_init_flag;
103 UINT8 CD_flag; /* 0x00 = CD-DA or <SEEK> or <SCAN> 0x80 = CD-ROM*/
104 UINT32 CD_repeat; /* repeat frequency*/
105 UINT32 CD_standby; /* standby wait*/
106 UINT32 CD_repeat_max; /* max repeat frequency*/
107 UINT8 CD_ecc;
108 UINT32 CD_drive_speed; /* 0 = noop, 1 = 1x, 2 = 2x*/
109
110
111 UINT8 cdda_buff[8192]; /* CD-DA buffer for SCSP communication*/
112 UINT32 cdda_pos;
113
114
115
116
117 /******************************************************************/
118
119 #define ISO_BUFF_SIZE (2352 * 16) /* cache size*/
120
121 /******************************************************************/
122
123 char * iso_buff = NULL;
124 static FILE * iso_file = NULL;
125 static UINT32 iso_media_present;
126 static UINT32 iso_mp3_init = 0;
127
128 UINT32 cdb_get_sect_size = 2048;
129 UINT32 cdb_put_sect_size = 2048;
130
131
fsize(FILE * f)132 INT32 fsize(FILE * f){
133
134 INT32 size=0;
135
136 if(f != NULL)
137 {
138
139 fseek(f, 0, SEEK_END);
140 size = ftell(f);
141 fseek(f, 0, SEEK_SET);
142 }
143 return(size);
144 }
145
146 static struct {
147
148 INT32 size; /* negative value means not present*/
149 UINT32 ctrl; /* control*/
150 UINT32 idx; /* index*/
151 UINT32 type; /* iso : sector size*/
152 UINT32 off; /* bin : offset info iso_file*/
153 UINT32 fad; /* position on the disc*/
154 UINT32 len; /* length (in sectors)*/
155 char path[256]; /* file path*/
156
157 } iso_track[100],
158 iso_leadout;
159
160 static UINT32 iso_track_first;
161 static UINT32 iso_track_last;
162 static UINT32 iso_track_num;
163
164 static INT32 iso_size; /* < 0 means not present*/
165 static UINT32 iso_type; /* 0 = ISO 1 = BIN*/
166
167 /******************************************************************/
168 /* CD Block Interface*/
169
170
171
cdb_inject_file_info(UINT32 fid,UINT8 * dst)172 void cdb_inject_file_info(UINT32 fid, UINT8 * dst){
173
174 /* converts standard cdb file info in saturn format*/
175 /* and 'injects' it in the supplied destination. ;)*/
176
177 dst[0x0] = CD_file[fid].fad >> 24;
178 dst[0x1] = CD_file[fid].fad >> 16;
179 dst[0x2] = CD_file[fid].fad >> 8;
180 dst[0x3] = CD_file[fid].fad;
181
182 dst[0x4] = CD_file[fid].size >> 24;
183 dst[0x5] = CD_file[fid].size >> 16;
184 dst[0x6] = CD_file[fid].size >> 8;
185 dst[0x7] = CD_file[fid].size;
186
187 dst[0x8] = CD_file[fid].gap;
188 dst[0x9] = CD_file[fid].unit;
189 dst[0xa] = fid;
190 dst[0xb] = CD_file[fid].attr;
191 }
192
cdb_find_track(UINT32 fad)193 UINT32 cdb_find_track(UINT32 fad){
194
195 /* finds the track that contains the specified fad*/
196
197 int i;
198
199 for(i = CD_toc.first.num-1; i < CD_toc.last.num-1; i++)
200 if(CD_toc.track[i].fad <= fad && CD_toc.track[i+1].fad > fad)
201 return(i+1);
202
203 if(fad && CD_toc.leadout.fad > fad)
204 return(CD_toc.last.num);
205
206 log_cb(RETRO_LOG_DEBUG, LOGPRE "ERROR: no track for the poor fad %x\n", fad);
207 exit(1);
208
209 return((INT32)-1);
210 }
211
cdb_find_file(UINT32 fad)212 UINT32 cdb_find_file(UINT32 fad){
213
214 /* finds the file that contains the specified fad*/
215
216 int i;
217
218 for(i = 0; i < CDB_FID_NUM; i++)
219 if((CD_file[i].fad <= fad) &&
220 ((CD_file[i].fad + (CD_file[i].size + 2047) / 2048) > fad))
221 return(i+2);
222
223 return(0); /* no file found (audio track) - not an error!*/
224 }
225
cdb_find_dest(UINT32 fnstv,UINT32 * pn)226 UINT32 cdb_find_dest(UINT32 fnstv, UINT32 * pn){
227
228 /* finds the sector data contained in *pn destination*/
229 /* according to the filters it must pass through.*/
230
231 filt_t * f;
232 UINT32 cond;
233
234 f = &CD_filt[fnstv];
235
236 do{
237 cond = 0;
238
239 if(f->mode & CDB_FILTMODE_RANGE){
240
241 if((CD_cur_fad < f->fad) ||
242 (CD_cur_fad >= (f->fad + f->range)))
243 cond = 1;
244 }
245
246 if(f->mode & CDB_FILTMODE_COD){
247
248 log_cb(RETRO_LOG_DEBUG, LOGPRE "ERROR: cod check required\n");
249 exit(1);
250 }
251
252 if(f->mode & CDB_FILTMODE_SUB){
253
254 log_cb(RETRO_LOG_DEBUG, LOGPRE "ERROR: sub check required\n");
255 exit(1);
256 }
257
258 if(f->mode & CDB_FILTMODE_CHAN){
259
260 log_cb(RETRO_LOG_DEBUG, LOGPRE "ERROR: chan check required\n");
261 exit(1);
262 }
263
264 if(f->mode & CDB_FILTMODE_FID){
265
266 if(f->fid) /* only if fid is valid*/
267 if(CD_cur_fid != f->fid) cond = 1;
268 }
269
270 if(cond == 0){
271
272 /* all checks passed, data is okay*/
273
274 if(f->true_cond == 0xff) /* disconnected*/
275 return(1); /* discard data*/
276
277 *pn = (UINT32)f->true_cond;
278 return(0);
279 }
280
281 if(f->false_cond != 0xff)
282 f = &CD_filt[f->false_cond];
283
284 }while(f->false_cond != 0xff);
285
286 return(1);
287 }
288
cdb_make_room(UINT32 pn)289 UINT32 cdb_make_room(UINT32 pn){
290
291 int i;
292
293 /* finds the first available free sector and*/
294 /* allocates it for use by the curent CDROM play*/
295 /* operation.*/
296
297 for(i = 0; i < 200; i++){
298
299 if(CD_sect[i].size == 0){
300
301 CD_sect[i].size = 2048;
302 CD_part[pn].sect[CD_part[pn].size] = &CD_sect[i];
303 CD_part[pn].size++;
304 CD_free_space--;
305
306 return(i);
307 }
308 }
309
310 /* should never happen, BFUL prevents it*/
311
312 log_cb(RETRO_LOG_DEBUG, LOGPRE "ERROR: cdb_make_room found no free sector\n");
313 exit(1);
314 }
315
316
317
318
319
320
321
322
323
324
325
326
327
328
iso_find_track(UINT32 fad)329 UINT32 iso_find_track(UINT32 fad){
330
331 int i;
332
333 for(i = iso_track_first-1; i < iso_track_last; i++)
334 if(iso_track[i].fad <= fad && iso_track[i+1].fad > fad)
335 return(i+1);
336
337 if(iso_leadout.fad > fad)
338 return(iso_track_last);
339
340 return((INT32)-1);
341 }
342
iso_read_sector(UINT32 mode,UINT32 fad,UINT8 * dst)343 UINT32 iso_read_sector(UINT32 mode, UINT32 fad, UINT8 * dst){
344
345 static char buff[2352];
346
347 log_cb(RETRO_LOG_DEBUG, LOGPRE "mode = %i fad = %i ", mode, fad);
348
349 if(iso_type == 0){
350
351 /* ISO*/
352
353 UINT32 tn;
354 FILE * f;
355
356 tn = iso_find_track(fad);
357
358 log_cb(RETRO_LOG_DEBUG, LOGPRE "track = %i ", tn);
359
360 f = fopen(iso_track[tn-1].path, "rb");
361 if(f == NULL){
362 log_cb(RETRO_LOG_DEBUG, LOGPRE "ERROR: couldn't open %s\n", iso_track[tn-1].path);
363 exit(1);
364 }
365
366 logerror( "reading fad:%x off:%x tn:%i from %s\n",
367 fad, fad - iso_track[tn-1].fad, tn, iso_track[tn-1].path);
368
369 fseek(f, (fad - iso_track[tn-1].fad) * 2048, SEEK_SET); /* 2352*/
370 if(fread(buff, 1, 2352, f) != 2352){
371 log_cb(RETRO_LOG_DEBUG, LOGPRE "ERROR: couldn't read from iso (fad = %06x)\n", fad);
372 exit(1);
373 }
374
375 fclose(f);
376
377 if(iso_track[tn-1].type != 0){
378
379 /* if CDDA or FORM 2 CDROM*/
380
381 log_cb(RETRO_LOG_DEBUG, LOGPRE " [2352] : %i\n", (fad - 150) * 2352);
382
383 if(mode == 0)
384 memcpy(dst, &buff[16], 2048);
385 else
386 memcpy(dst, buff, 2352);
387
388 return(mode);
389
390 }else{
391
392 /* CDROM*/
393
394 log_cb(RETRO_LOG_DEBUG, LOGPRE " [2048] : %i\n", (fad - 150) * 2048);
395
396 if(mode == 0)
397 memcpy(dst, buff, 2048);
398 else
399 memcpy(&dst[16], buff, 2048);
400
401 return(0);
402 }
403 }
404
405 /* BIN*/
406
407 return(0);
408 }
409
iso_seek_sector(UINT32 fad)410 void iso_seek_sector(UINT32 fad){
411
412 }
413
414 /********************************************************/
415
iso_get_track_info(UINT32 tn,UINT32 * ctrl,UINT32 * idx,UINT32 * fad)416 UINT32 iso_get_track_info(UINT32 tn, UINT32 * ctrl, UINT32 * idx, UINT32 * fad){
417
418 if(tn < iso_track_first || tn > iso_track_last)
419 return(1);
420
421 *fad = iso_track[tn-1].fad;
422 *ctrl = iso_track[tn-1].ctrl;
423 *idx = iso_track[tn-1].idx;
424
425 return(0);
426 }
427
iso_get_leadout_info(UINT32 * ctrl,UINT32 * idx,UINT32 * fad)428 void iso_get_leadout_info(UINT32 * ctrl, UINT32 * idx, UINT32 * fad){
429
430 *fad = iso_leadout.fad;
431 *ctrl = iso_track[iso_track_last-1].ctrl;
432 *idx = iso_track[iso_track_last-1].idx;
433 }
434
iso_get_first_track(void)435 UINT32 iso_get_first_track(void){ return(iso_track_first); }
iso_get_last_track(void)436 UINT32 iso_get_last_track(void){ return(iso_track_last); }
437
438 /********************************************************/
439
iso_get_status(void)440 UINT32 iso_get_status(void){
441
442 UINT32 stat;
443
444 stat = 0;
445
446 /* if(iso_media_present) stat |= CDSTAT_MEDIA_PRESENT;*/
447
448 /* stat |= CDSTAT_CAN_RAW_AUDIO;*/
449
450 return(stat);
451 }
452
453 /********************************************************/
454 /* Local Procedures*/
455
iso_build_disc_bin(void)456 static void iso_build_disc_bin(void){
457
458 /* log_cb(RETRO_LOG_DEBUG, LOGPRE "loading BIN: %s\n", config.cdrom_image);*/
459 exit(1);
460 }
461
iso_build_disc_iso(void)462 static void iso_build_disc_iso(void){
463
464 /*char b[2048];*/
465 char s[256], t[256];
466 FILE * f;
467 int i, j;
468 UINT32 fad;
469
470 /* char fmt[][12] = {*/
471 /* "%02d.iso", "-%02d.iso", "_%02d.iso", " %02d.iso",*/
472 /* "%02d.wav", "-%02d.wav", "_%02d.wav", " %02d.wav",*/
473 /* "%02d.mp3", "-%02d.mp3", "_%02d.mp3", " %02d.mp3",*/
474 /* };*/
475
476 char fmt[3][12] = {
477 "%02d.iso",
478 "%02d.wav",
479 "%02d.mp3",
480 };
481
482 strcpy(s, "roms/sfish2");
483 strcat(s, "/track_");
484
485 fad = 150;
486
487 iso_track_first = 100;
488 iso_track_last = 1;
489
490 for(i = 1; i < 100; i++){
491
492 for(j = 0; j < 3; j++){
493
494 strcpy(t, s);
495 strcat(t, fmt[j]);
496 sprintf(t, t, i);
497
498 f = fopen(t, "rb");
499 if(f != NULL){
500
501 log_cb(RETRO_LOG_DEBUG, LOGPRE "found track : %s\n", t);
502
503 if(iso_track_first > i) iso_track_first = i;
504 if(iso_track_last < i) iso_track_last = i;
505
506 if(i == 1)
507 iso_media_present = 1;
508
509 if(j == 0){
510
511 /* ISO file*/
512
513 if(i == 1){
514 /*
515 // first track
516 log_cb(RETRO_LOG_DEBUG, LOGPRE "1, lunghezza %d, iso buff contiene %s\n",fsize(f),iso_buff);
517 fseek(f, 0, SEEK_SET);
518 int pp=fread(iso_buff, 1, 0x110, f);
519 fseek(f, 0, SEEK_SET);
520 log_cb(RETRO_LOG_DEBUG, LOGPRE "2\n");
521 log_cb(RETRO_LOG_DEBUG, LOGPRE "%d\t%s\n",pp,iso_buff);
522
523 if(strncmp(&iso_buff[0x00], "SEGA SEGASATURN ", 16)){
524 log_cb(RETRO_LOG_DEBUG, LOGPRE "2b\n");
525 // ISO 2048-bytes data track
526
527 //setup_game_info(&iso_buff[0x00]);
528 //setup_area_symbol(iso_buff[0x40]);
529
530 }else
531 if(strncmp(&iso_buff[0x10], "SEGA SEGASATURN ", 16)){
532
533 // ISO 2352-bytes data track
534
535 //setup_game_info(&iso_buff[0x10]);
536 //setup_area_symbol(iso_buff[0x50]);
537
538 iso_track[i-1].type = 1;
539
540 }else{
541
542 log_cb(RETRO_LOG_DEBUG, LOGPRE "ERROR: unknown track %i format (file: %s)\n", i, t);
543 exit(1);
544 }
545 log_cb(RETRO_LOG_DEBUG, LOGPRE "3\n");
546 memset(iso_buff, 0x00, 0x110);
547
548 iso_track[i-1].type = 0; // 2048-bytes
549 */
550 }else{
551
552 /* non-first track*/
553 /* assume ISO 2352-bytes data track*/
554
555 iso_track[i-1].type = 1; /* 2352-bytes*/
556 }
557
558 iso_track[i-1].size = fsize(f);
559 iso_track[i-1].ctrl = 4;
560 iso_track[i-1].idx = 1;
561 iso_track[i-1].off = 0;
562 iso_track[i-1].fad = fad;
563 iso_track[i-1].len = (iso_track[i-1].size + 2047) / 2048;
564
565 }else
566 if(j == 1){
567
568 /* WAV file*/
569
570 iso_track[i-1].size = fsize(f);
571 iso_track[i-1].ctrl = 1;
572 iso_track[i-1].idx = 1;
573 iso_track[i-1].type = 1; /* WAV, 2352-bytes*/
574 iso_track[i-1].off = 0;
575 iso_track[i-1].fad = fad;
576 iso_track[i-1].len = (fsize(f) + 2047) / 2048;
577
578 }else{
579
580 /* MP3 file*/
581
582 if(!iso_mp3_init){
583 /* mp3_init();*/
584 iso_mp3_init = 1;
585 }
586
587 iso_track[i-1].size = fsize(f); /* fixme*/
588 iso_track[i-1].ctrl = 1;
589 iso_track[i-1].idx = 1;
590 iso_track[i-1].type = 2; /* MP3*/
591 iso_track[i-1].off = 0;
592 iso_track[i-1].fad = fad;
593 iso_track[i-1].len = (fsize(f) + 2047) / 2048; /* fixme*/
594 }
595
596 strcpy(iso_track[i-1].path, t);
597
598 fad += iso_track[i-1].len;
599
600 fclose(f);
601 }
602 }
603 }
604
605 iso_leadout.fad = iso_track[iso_track_last-1].fad+iso_track[iso_track_last-1].len + 150; /* 2 sec after the last track*/
606
607 iso_track_num = (iso_track_last - (iso_track_first - 1));
608
609 iso_type = 0;
610 }
611
612 /********************************************************/
613
iso_shutdown(void)614 void iso_shutdown(void){
615
616 if(iso_buff != NULL){ free(iso_buff); iso_buff = NULL; }
617 if(iso_file != NULL){ fclose(iso_file); iso_file = NULL; }
618 }
619
iso_reset(void)620 void iso_reset(void){
621
622 int i;
623
624 iso_media_present = 0;
625 iso_size = -1;
626 iso_type = 0;
627
628 iso_shutdown();
629
630 for(i = 0; i < 100; i++){
631
632 iso_track[i].size = -1;
633 iso_track[i].ctrl = 0;
634 iso_track[i].idx = 0;
635 iso_track[i].off = 0;
636 iso_track[i].fad = 0;
637 iso_track[i].len = 0;
638
639 strcpy(iso_track[i].path, "NULL");
640 }
641
642 iso_build_disc_iso(); /* supposed ISO image*/
643 }
644
iso_init(void)645 void iso_init(void){
646
647 }
648
649
650
FAD_TO_MIN(UINT32 fad)651 UINT32 FAD_TO_MIN(UINT32 fad){
652 /*
653 UINT32 tmp=fad/75;
654 UINT32 tmp2=0;
655 while (tmp>60){
656 tmp -=60;
657 tmp2++;
658 }
659 return(tmp2);
660 */
661 return (fad/4500);
662 }
663
FAD_TO_SEC(UINT32 fad)664 UINT32 FAD_TO_SEC(UINT32 fad){
665 /*
666 UINT32 tmp=fad/75;
667 while (tmp>60){
668 tmp -=60;
669 }
670 return(tmp);
671 */
672 return( (fad/75) %60);
673 }
674
FAD_TO_FRA(UINT32 fad)675 UINT32 FAD_TO_FRA(UINT32 fad){
676
677 return(fad%75);
678 }
679
cdb_build_toc(void)680 void cdb_build_toc(void){
681
682 UINT32 ctrl, idx, fad;
683 int i;
684 int oo=0;
685
686 memset(CD_sat_toc, 0xff, 0xcc*2);
687 memset(&CD_toc.track, 0xff, sizeof(track_t)*100);
688
689 CD_toc.first.num = iso_get_first_track();
690 CD_toc.last.num = iso_get_last_track();
691
692 logerror(
693 "%i tracks found (first:%i last:%i)\n",
694 (CD_toc.last.num - (CD_toc.first.num - 1)),
695 CD_toc.first.num,
696 CD_toc.last.num
697 );
698
699 for(i = CD_toc.first.num-1; i <= CD_toc.last.num-1; i++){
700
701 if(iso_get_track_info(i+1, &ctrl, &idx, &fad)){
702 log_cb(RETRO_LOG_DEBUG, LOGPRE "ERROR: error on cdb_build_toc, iso_get_track_info tn=%i\n", i+1);
703 exit(1);
704 }
705
706 CD_toc.track[i].ctrl = (ctrl << 4);
707 CD_toc.track[i].idx = idx;
708 CD_toc.track[i].fad = fad;
709 CD_toc.track[i].min = FAD_TO_MIN(fad);
710 CD_toc.track[i].sec = FAD_TO_SEC(fad);
711 CD_toc.track[i].fra = FAD_TO_FRA(fad);
712
713 CD_sat_toc[(i*4)+0] = (ctrl << 4) | idx;
714 CD_sat_toc[(i*4)+1] = (UINT8)((UINT32)fad >> 16);
715 CD_sat_toc[(i*4)+2] = (UINT8)((UINT32)fad >> 8);
716 CD_sat_toc[(i*4)+3] = (UINT8)((UINT32)fad);
717
718 logerror("track#%02i: %02i:%02i:%02i (addr: %i ctrl:%i idx:%i)\n",
719 i+1, FAD_TO_MIN(fad), FAD_TO_SEC(fad), FAD_TO_FRA(fad), fad, ctrl, idx);
720 }
721
722 CD_toc.first.ctrl = CD_toc.track[CD_toc.first.num-1].ctrl;
723 CD_toc.first.idx = CD_toc.track[CD_toc.first.num-1].idx;
724 CD_toc.first.fad = CD_toc.track[CD_toc.first.num-1].fad;
725 CD_toc.first.min = CD_toc.track[CD_toc.first.num-1].min;
726 CD_toc.first.sec = CD_toc.track[CD_toc.first.num-1].sec;
727 CD_toc.first.fra = CD_toc.track[CD_toc.first.num-1].fra;
728
729 CD_sat_toc[0x18c] = (CD_toc.first.ctrl) | CD_toc.first.idx;
730 CD_sat_toc[0x18d] = CD_toc.first.num;
731 CD_sat_toc[0x18e] = 0x00; /* psec ?*/
732 CD_sat_toc[0x18f] = 0x00; /* pfra ?*/
733
734 logerror("track#%02i: %02i:%02i:%02i (addr: %i)\n",
735 CD_toc.first.num, CD_toc.first.min, CD_toc.first.sec, CD_toc.first.fra, CD_toc.first.fad);
736
737 CD_toc.last.ctrl = CD_toc.track[CD_toc.last.num-1].ctrl;
738 CD_toc.last.idx = CD_toc.track[CD_toc.last.num-1].idx;
739 CD_toc.last.fad = CD_toc.track[CD_toc.last.num-1].fad;
740 CD_toc.last.min = CD_toc.track[CD_toc.last.num-1].min;
741 CD_toc.last.sec = CD_toc.track[CD_toc.last.num-1].sec;
742 CD_toc.last.fra = CD_toc.track[CD_toc.last.num-1].fra;
743
744 CD_sat_toc[0x190] = (CD_toc.last.ctrl) | CD_toc.last.idx;
745 CD_sat_toc[0x191] = CD_toc.last.num;
746 CD_sat_toc[0x192] = 0x00; /* psec ?*/
747 CD_sat_toc[0x193] = 0x00; /* pfra ?*/
748
749 logerror("track#%02i: %02i:%02i:%02i (addr: %i)\n",
750 CD_toc.last.num, CD_toc.last.min, CD_toc.last.sec, CD_toc.last.fra, CD_toc.last.fad);
751
752 iso_get_leadout_info(&ctrl, &idx, &fad);
753
754 CD_toc.leadout.ctrl = ctrl;
755 CD_toc.leadout.idx = idx;
756 CD_toc.leadout.fad = fad;
757 CD_toc.leadout.min = FAD_TO_MIN(fad);
758 CD_toc.leadout.sec = FAD_TO_SEC(fad);
759 CD_toc.leadout.fra = FAD_TO_FRA(fad);
760
761 CD_sat_toc[0x194] = (ctrl << 4) | idx;
762 CD_sat_toc[0x195] = (UINT8)((UINT32)fad >> 16);
763 CD_sat_toc[0x196] = (UINT8)((UINT32)fad >> 8);
764 CD_sat_toc[0x197] = (UINT8)((UINT32)fad);
765
766 logerror("leadout: %02i:%02i:%02i (addr: %i)\n",
767 CD_toc.leadout.min, CD_toc.leadout.sec, CD_toc.leadout.fra, CD_toc.leadout.fad);
768
769 log_cb(RETRO_LOG_DEBUG, LOGPRE "\n\nTOC DUMP\n\n");
770 while (oo<408){
771 log_cb(RETRO_LOG_DEBUG, LOGPRE "%2x %2x %2x %2x\n", CD_sat_toc[oo],CD_sat_toc[oo+1],CD_sat_toc[oo+2],CD_sat_toc[oo+3]);
772 oo+=4;
773 }
774
775 }
776
777
cdb_build_ftree(void)778 void cdb_build_ftree(void){
779
780 UINT32 addr, fad, off;
781 UINT32 i, j, size;
782
783 static UINT8 buff[4096];
784
785 addr = 40960;
786 fad = (addr / 2048) + 150;
787 off = (addr & 2047);
788
789 i = 0;
790
791 while(fad < CD_toc.leadout.fad && i < CDB_FID_NUM){
792
793 iso_read_sector(0, fad+0, &buff[2048 * 0]);
794 iso_read_sector(0, fad+1, &buff[2048 * 1]);
795
796 size = buff[off+0x00];
797
798 if(size == 0){
799 /* check for subdirs*/
800 break;
801 }
802
803 CD_file[i].fad = (buff[off+0x06] << 24) | (buff[off+0x07] << 16) | (buff[off+0x08] << 8) | buff[off+0x09];
804 CD_file[i].size = (buff[off+0x0e] << 24) | (buff[off+0x0f] << 16) | (buff[off+0x10] << 8) | buff[off+0x11];
805 CD_file[i].attr = buff[off+0x19];
806 CD_file[i].unit = buff[off+0x1a];
807 CD_file[i].gap = buff[off+0x1b];
808 CD_file[i].name_len = (buff[off+0x20] > 32) ? 32 : buff[off+0x20];
809
810 for(j = 0; j < CD_file[i].name_len; j++)
811 CD_file[i].name[j] = buff[off+0x21+j];
812 CD_file[i].name[j] = '\0';
813
814 CD_file[i].fad += 150; /* LSN to FAD*/
815
816 logerror( "ANY 2 #%08i : (fad=%i off=%i, size=%02X) fad=%06X size=%06X attr=%02X %s\n",
817 i, fad, off, size,
818 CD_file[i].fad,
819 CD_file[i].size,
820 CD_file[i].attr,
821 CD_file[i].name
822 );
823
824 addr += size;
825 fad = (addr / 2048) + 150;
826 off = (addr & 2047);
827 i++;
828 }
829
830 CD_file_num = (i < 2) ? 2 : i; /* to prevent stupid ISO bugs*/
831 log_cb(RETRO_LOG_DEBUG, LOGPRE "trovati %d file\n",CD_file_num);
832 }
833
CD_com_update(UINT32 count)834 void CD_com_update(UINT32 count){
835
836
837 if(!CD_cr_writing && !CD_cr_first) {
838
839
840
841 log_cb(RETRO_LOG_DEBUG, LOGPRE "---- periodic update ----\n");
842
843 /* prevents update to change anything before*/
844 /* the init string is read by the host*/
845 /*if(CD_cr_first) return ();*/
846
847 /* prevents update from overwriting cr registers*/
848 /* while a command is being written*/
849 /*if(CD_cr_writing) return ();*/
850
851 if(CD_status == CDB_STAT_PAUSE){
852
853 if(CD_free_space && (CD_hirq & HIRQ_BFUL)){
854
855 /* PEND ?*/
856
857 log_cb(RETRO_LOG_DEBUG, LOGPRE "BFUL -> PLAY\n");
858
859 CD_hirq &= ~HIRQ_BFUL;
860 CD_status = CDB_STAT_PLAY;
861 }
862 }
863
864 if(CD_status == CDB_STAT_PLAY){
865
866 if(CD_toc.track[CD_cur_track-1].ctrl & 0x40){
867
868 /* CDROM*/
869
870 UINT32 pn;
871
872 if(cdb_find_dest(CD_filt_num, &pn) == 0){
873
874 /* dest partition found, else data is discarded*/
875
876 UINT32 sn;
877
878 sn = cdb_make_room(pn);
879
880 CD_part[pn].sect[sn]->size = cdb_get_sect_size; /* 2048, 2352*/
881 CD_part[pn].sect[sn]->fad = CD_cur_fad;
882 CD_part[pn].sect[sn]->fid = CD_cur_fid;
883 CD_part[pn].sect[sn]->chan = 0;
884 CD_part[pn].sect[sn]->sub = 0;
885 CD_part[pn].sect[sn]->cod = 0;
886
887 logerror("PLAY CDROM : fad=%06x [%06x~%06x] track=%i ctrl=%x idx=%i -> pn=%i sn=%i\n",
888 CD_cur_fad, CD_play_fad, CD_play_fad+CD_play_range,
889 CD_cur_track, CD_cur_ctrl, CD_cur_idx, pn, sn);
890
891 if(iso_read_sector(1, CD_cur_fad, CD_part[pn].sect[sn]->data) == 0 &&
892 2048 != 2048){
893
894 #if 0
895
896 /* couldn't read synch, header, subheader*/
897 /* and EDC/ECC data. generate it! (FORM2 MODE1)*/
898
899 /* synch data (12 bytes)*/
900 memset(&CD_part[pn].sect[sn]->data[1], 0xff, 10);
901 CD_part[pn].sect[sn]->data[0] = 0x00;
902 CD_part[pn].sect[sn]->data[11] = 0x00;
903
904 /* header (4 bytes)*/
905 CD_part[pn].sect[sn]->data[12] = FAD_TO_MIN(CD_cur_fad); /* min*/
906 CD_part[pn].sect[sn]->data[13] = FAD_TO_SEC(CD_cur_fad); /* sec*/
907 CD_part[pn].sect[sn]->data[14] = FAD_TO_FRA(CD_cur_fad); /* fra*/
908 CD_part[pn].sect[sn]->data[15] = 0; /* mode*/
909
910 /* subheader (8 bytes)*/
911
912 /* EDC/ECC*/
913 memset(&CD_part[pn].sect[sn]->data[2048+16+8], 0xff, 280);
914
915 #endif
916 }
917
918 if(CD_free_space <= 0){
919
920 /* buffer full*/
921
922 log_cb(RETRO_LOG_DEBUG, LOGPRE "BFUL!\n");
923
924 CD_hirq |= HIRQ_BFUL;
925 /* CD_hirq |= HIRQ_PEND; */ /* not sure*/
926 CD_hirq |= HIRQ_DRDY; /* not sure*/
927
928 CD_status = CDB_STAT_PAUSE;
929 }
930 }
931
932 CD_flag = CD_FLAG_CDROM;
933
934 }else{
935
936 /* CDDA*/
937
938 logerror("PLAY CDDA : fad=%06x [%06x~%06x] track=%i ctrl=%i idx=%i\n",
939 CD_cur_fad, CD_play_fad, CD_play_fad+CD_play_range,
940 CD_cur_track, CD_cur_ctrl, CD_cur_idx);
941
942 CD_flag = 0; /* playing CDDA*/
943
944 /* set 1x drive speed*/
945
946 /*CD_update_timings(1);*/
947
948 /* fill the CD-DA buffer*/
949
950 if(iso_read_sector(1, CD_cur_fad, &cdda_buff[cdda_pos & (8192 - 1)]) == 0){
951
952 /* not all the 2352 data could be read*/
953 /* CD-DA cannot be played*/
954
955 memset(cdda_buff, 0x00, 8192);
956
957 }else{
958
959 /* the CD-DA data resides in cdda_buff[]*/
960 }
961
962 cdda_pos += 2352;
963
964 /* update subcode info for *next* sector*/
965
966 {
967
968 /* generate subcode q*/
969
970 UINT32 pfad, qfad;
971
972 pfad = (CD_cur_fad + 1) - CD_toc.first.fad;
973 qfad = (CD_cur_fad + 1);
974
975 CD_sat_subq[0] = CD_toc.track[CD_cur_track-1].ctrl | 1; /* ctrl, adr*/
976 CD_sat_subq[1] = CD_cur_track; /* tno*/
977 CD_sat_subq[2] = 1; /* idx*/
978 CD_sat_subq[3] = pfad >> 16; /* pfad*/
979 CD_sat_subq[4] = pfad >> 8; /* pfad*/
980 CD_sat_subq[5] = pfad; /* pfad*/
981 CD_sat_subq[6] = 0x00; /* -*/
982 CD_sat_subq[7] = qfad >> 16; /* qfad*/
983 CD_sat_subq[8] = qfad >> 8; /* qfad*/
984 CD_sat_subq[9] = qfad; /* qfad*/
985
986 /* generate subcode rw*/
987
988 memset(CD_sat_subrw, 0x00, 24); /* eeer ... ;)*/
989
990 }
991 }
992
993 CD_cur_fad++; /* points to *next* sector*/
994
995 CD_cur_track = iso_find_track(CD_cur_fad);
996 CD_cur_ctrl = CD_toc.track[CD_cur_track-1].ctrl;
997 CD_cur_idx = CD_toc.track[CD_cur_track-1].idx;
998 /*CD_cur_fid = iso_find_file(CD_cur_fad);*/
999
1000 if((CD_cur_fad < CD_play_fad) ||
1001 (CD_cur_fad >= (CD_play_fad + CD_play_range))){
1002
1003 if(((CD_flag & 0x80) == 0) && /* CD-DA*/
1004 (CD_repeat_max != 0xff) && /* no ignore errors*/
1005 ((CD_repeat_max == 0xfe) || /* infinite repeat*/
1006 (CD_repeat < CD_repeat_max))){ /* didn't finish number of repeats*/
1007
1008 /* setup repeat*/
1009
1010 log_cb(RETRO_LOG_DEBUG, LOGPRE "REPEAT (%i / %i)\n", CD_repeat, CD_repeat_max);
1011
1012 }else{
1013
1014 /* play ended*/
1015
1016 log_cb(RETRO_LOG_DEBUG, LOGPRE "PLAY ended\n");
1017
1018 CD_status = CDB_STAT_PAUSE;
1019
1020 CD_hirq |= HIRQ_PEND;
1021 if(CD_flag != 0)
1022 CD_hirq |= HIRQ_DRDY;
1023
1024 CD_flag = 0;
1025
1026 /* return to default speed (not correct, but can do it)*/
1027 /* should be done on next pickup-movement command instead*/
1028
1029 /*CD_update_timings(CD_drive_speed);*/
1030 }
1031 }
1032
1033 CD_hirq |= HIRQ_SCDQ;
1034 CD_hirq |= HIRQ_CSCT; /* shouldn't be here!*/
1035
1036 }else
1037 if(CD_status == CDB_STAT_SCAN){
1038
1039 CD_flag = 0;
1040
1041 if((CD_scan_dir == 0) && /* scanning forward*/
1042 (CD_toc.track[CD_cur_track-1].ctrl & 0x40) == 0){ /* CDDA*/
1043
1044 /* play CDDA*/
1045
1046 log_cb(RETRO_LOG_DEBUG, LOGPRE "SCAN - PLAY CDDA\n");
1047
1048 /* set 1x drive speed*/
1049
1050 /*CD_update_timings(1);*/
1051 }
1052
1053 /* update fad*/
1054
1055
1056
1057 log_cb(RETRO_LOG_DEBUG, LOGPRE "ERROR: scanning\n");
1058 /*exit(1);*/
1059 }
1060
1061 CD_hirq |= HIRQ_SCDQ;
1062
1063 CDB_SEND_REPORT();
1064 CR1 |= CDB_STAT_PERI << 8; /* periodic response*/
1065 }
1066 log_cb(RETRO_LOG_DEBUG, LOGPRE "CD block update\n");
1067 }
1068