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