1 #include "osd_win_cd.h"
2 #include "cleantyp.h"
3 
4 #if defined(ALLEGRO)
5 
6 #include <windows.h>
7 #include "myaspi32.h"
8 
9 static int HaId;
10 static int Target;
11 static int Lun;
12 static int aspi_init = 0;
13 
ReadToc()14 DWORD (*pfnGetASPI32SupportInfo) (void);
15 DWORD (*pfnSendASPI32Command) (LPSRB);
16 
17 #pragma pack(1)
18 
19 typedef struct
20 {
21   BYTE rsvd;
22   BYTE ADR;
23   BYTE trackNumber;
24   BYTE rsvd2;
ReadDevice(int H,int T,int L)25   BYTE addr[4];
26 }
27 PACKED TOCTRACK;
MSB2DWORD(DWORD * d,BYTE * b)28 
29 typedef struct
30 {
31   WORD tocLen;
32   BYTE firstTrack;
33   BYTE lastTrack;
34   TOCTRACK tracks[100];
35 }
36 PACKED TOC, *PTOC, FAR * LPTOC;
37 
38 #pragma pack()
39 
40 static TOC toc;
41 
42 DWORD
osd_cd_close()43 ReadToc ()
44 {
45 
46   SRB_ExecSCSICmd s;
47   HANDLE hEvent;
48   DWORD dwStatus;
49 	/*
50  if (aspi_init == 0)
51    loadASPI();
52 */
53   Log("Reading TOC\n");
54 
55   hEvent = CreateEvent (NULL, TRUE, FALSE, NULL);
56 
57 	  memset (&s, 0, sizeof (s));
58 	  memset (&toc, 0, sizeof (toc));
59 	  s.SRB_Cmd = SC_EXEC_SCSI_CMD;
60 
61 
62 	  s.SRB_HaID = HaId;
63 	  s.SRB_Target = Target;
64 	  s.SRB_Lun = Lun;
65 	  s.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY;
66 	  s.SRB_BufLen = 0x324;
67 	  s.SRB_BufPointer = (BYTE FAR *) & toc;
68 	  s.SRB_SenseLen = 0x0E;
69 	  s.SRB_CDBLen = 0x0A;
70 	  s.SRB_PostProc = (LPVOID) hEvent;
71 	  s.CDBByte[0] = 0x43;	// command to read TOC
72 	  s.CDBByte[7] = 0x03;	// ofs. 7-8 used for toc len
73 	  s.CDBByte[8] = 0x24;	// TOC buffer length == 0x324
74 
75 	  dwStatus = pfnSendASPI32Command ((LPSRB) & s);
76 
77           if (dwStatus == SS_PENDING)
78 	    {
79 	      WaitForSingleObject (hEvent, INFINITE);
80 	    }
81 
82 		{
83 			int i;
84 			Log("First track: %d\nLast track: %d\n", toc.firstTrack, toc.lastTrack);
85 
86 			for (i = toc.firstTrack; i <= toc.lastTrack; i++) {
87 			  Log("Track %d: %d\n", i, toc.tracks[i-1].addr);
88 			}
89 		}
90 
91           CloseHandle(hEvent);
92 
93           return s.SRB_Status;
94  }
95 
96 DWORD
97 ReadDevice (int H,
98             int T,
99             int L)
100 {
101 
102   SRB_GDEVBlock s;
103   HANDLE hEvent;
104   DWORD dwStatus;
105 
106   /*
107   if (aspi_init == 0)
108    loadASPI();
109   */
110 
111   hEvent = CreateEvent (NULL, TRUE, FALSE, NULL);
112 
113 	  memset (&s, 0, sizeof (s));
114 
115           s.SRB_Cmd = SC_GET_DEV_TYPE;
116 
117           s.SRB_HaID = H;
118           s.SRB_Target = T;
119           s.SRB_Lun = L;
120 
121 	  dwStatus = pfnSendASPI32Command ((LPSRB) & s);
122 
123           if (dwStatus == SS_PENDING)
124 	    {
125 	      WaitForSingleObject (hEvent, INFINITE);
126               return -1;
127 	    }
128 
129           CloseHandle(hEvent);
130 
131           if (dwStatus == SS_COMP)
132             return s.SRB_DeviceType;
133 
134           return -1;
135  }
136 
137 
138 int
139 loadASPI (void)
140 {
141   HINSTANCE hDll;
142 
143   hDll = LoadLibrary ("WNASPI32.DLL");
144   if (!hDll)
145     return 0;
146 
147   pfnGetASPI32SupportInfo =
148     (DWORD (*)(void)) GetProcAddress (hDll, "GetASPI32SupportInfo");
149   pfnSendASPI32Command =
150     (DWORD (*)(LPSRB)) GetProcAddress (hDll, "SendASPI32Command");
151 
152   if (!pfnGetASPI32SupportInfo || !pfnSendASPI32Command)
153     {
154       Log("Win Aspi NOT initiated\n");
155       return 0;
156     }
157 
158   aspi_init = 1;
159 
160   Log("Win Aspi initiated\n");
161 
162   return -1;
163 }
164 
165 void
166 MSB2DWORD (DWORD * d, BYTE * b)
167 {
168   DWORD retVal;
169 
170   retVal = (DWORD) b[0];
171   retVal = (retVal << 8) + (DWORD) b[1];
172   retVal = (retVal << 8) + (DWORD) b[2];
173   retVal = (retVal << 8) + (DWORD) b[3];
174 
175   *d = retVal;
176 }
177 
178 int osd_cd_init(char* device)
179 {
180  int HaId_in, Target_in, Lun_in;
181  int nb = atoi(device);
182 
183  Log("Init win aspi cdrom device\n");
184 
185  if (nb == 0)
186    nb = 1;
187 
188 /*
189 
190  if (loadASPI())
191 
192    return 1;
193 
194 */
195 
196  Log("Trying to check cd driver number %d\n", nb);
197 
198  loadASPI();
199 
200  for (HaId_in = 0; HaId_in < 8; HaId_in++)
201     for (Target_in = 0; Target_in < 8; Target_in++)
202        for (Lun_in = 0; Lun_in < 8; Lun_in++)
203           {
204 /*
205           Log("Trying %d:%d:%d\n",
206                       HaId_in,
207                       Target_in,
208                       Lun_in);
209 */
210           if (ReadDevice(HaId_in,
211                          Target_in,
212                          Lun_in) != 5)
213             continue;
214 /*
215           Log("Found 1 CD...\n");
216 */
217           if (--nb)
218             continue;
219 
220 	  Log ("CD found at %d:%d:%d\n", HaId_in, Target_in, Lun_in);
221 
222           HaId = HaId_in;
223           Target = Target_in;
224           Lun = Lun_in;
225 
226 		  ReadToc();
227 
228           return 0;
229 
230           }
231 
232     return 1;
233 }
234 
235 void osd_cd_close()
236 {
237 }
238 
239 void osd_cd_read(UChar* p, UInt32 sector)
240 {
241   HANDLE hEvent;
242   SRB_ExecSCSICmd s;
243   DWORD dwStatus;
244   // BYTE* intern_buffer = (BYTE*)malloc(2352);
245 
246 	printf("Reading sector %d in %s - %s\n", sector, __FILE__, __LINE__);
247 
248 	return;
249 
250 	/*
251  if (aspi_init == 0)
252    loadASPI();
253 
254 		  hEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
255 
256 		  memset (&s, 0, sizeof (s));
257 		  s.SRB_Cmd = SC_EXEC_SCSI_CMD;
258 		  s.SRB_HaID = HaId;
259 		  s.SRB_Target = Target;
260 		  s.SRB_Lun = Lun;
261 		  s.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY;
262 		  s.SRB_BufLen = 2352;
263 		  s.SRB_BufPointer = intern_buffer;
264 		  s.SRB_SenseLen = SENSE_LEN;
265 		  s.SRB_CDBLen = 12;
266 		  s.SRB_PostProc = (LPVOID) hEvent;
267 
268 
269 		  s.CDBByte[0] = 0xBE;	// read CD Raw
270                   s.CDBByte[3] = (sector >> 16) & 0xFF;
271                   s.CDBByte[4] = (sector >> 8) & 0xFF;
272                   s.CDBByte[5] = sector & 0xFF;
273 
274                   s.CDBByte[8] = 1;
275 
276 		  s.CDBByte[9] = 0xF0;
277 
278 		  ResetEvent (hEvent);
279 		  dwStatus = pfnSendASPI32Command ((LPSRB) & s);
280 		  if (dwStatus == SS_PENDING)
281 		    {
282 		      WaitForSingleObject (hEvent, INFINITE);
283 		    }
284 
285 		  if (s.SRB_Status != SS_COMP) {
286 			  free(intern_buffer);
287                     return s.SRB_Status;
288 		  }
289 
290 		  CloseHandle( hEvent );
291 
292                   memcpy(p, intern_buffer + 16, 2048);
293 
294 		  free(intern_buffer);
295 
296                   return s.SRB_Status;
297 */
298 
299 }
300 
301 void osd_cd_stop_audio()
302 {
303 }
304 
305 void osd_cd_track_info( UChar track,
306 			int* min,
307 			int* sec,
308 			int* fra,
309 			int* control)
310 {
311  DWORD frame;
312 
313  Log("Looking for track info of #%d - %s %d\n", track, __FILE__, __LINE__);
314 
315  track--;
316 
317  *control = ((TOCTRACK)(toc.tracks[track])).ADR;
318 
319  MSB2DWORD( &frame, ((TOCTRACK)(toc.tracks[track])).addr );
320 
321  Frame2Time(frame + 150, min, sec, fra);
322 
323  Log("Track begins at frame %d\n", frame + 150);
324 
325 }
326 
327 void osd_cd_nb_tracks(int* first,
328 		      int* last)
329 {
330 
331  if (aspi_init == 0)
332    loadASPI();
333 
334  // ReadToc();
335 
336  Log("Will output tracks limit\n");
337 
338  *first = toc.firstTrack;
339  *last = toc.lastTrack;
340 
341 }
342 
343 void osd_cd_length(int* min,
344                    int* sec,
345                    int* fra)
346 {
347  *min = 25;
348  *sec = 06;
349  *fra = 00;
350 }
351 
352 void osd_cd_play_audio_track(UChar track)
353 {
354 }
355 
356 void osd_cd_play_audio_range(
357 			     UChar min_from,
358 			     UChar sec_from,
359 			     UChar fra_from,
360 			     UChar min_to,
361 			     UChar sec_to,
362 			     UChar fra_to)
363 {
364 }
365 
366 void osd_cd_subchannel_info(unsigned short offset)
367 {
368   Wr6502(offset, 4);
369   }
370 
371 
372 void osd_cd_status(int *status)
373 {
374       *status = 0;
375 }
376 
377 void osd_cd_pause(void)
378 {
379 }
380 
381 
382 void osd_cd_resume(void)
383 {
384 }
385 
386 #else
387 
388 #include <windows.h>
389 #include <stdio.h>
390 #include "akrip32.h"
391 #include <SDL.h>
392 
393 int akrip_init = 0;
394 
395 SDL_CD *cdrom;
396 
397 void MSB2DWORD( DWORD *d, BYTE *b );
398 LPTRACKBUF NewTrackBuf( DWORD numFrames );
399 
400 static LPTRACKBUF track_buffer;
401 static HCDROM handle_CD;
402 static TOC toc;
403 
404 int akrip_read(HCDROM hCD, unsigned int sector)
405 {
406   DWORD dwStatus;
407 
408   track_buffer->numFrames = 1;
409   track_buffer->startOffset = 0;
410   track_buffer->len = 0;
411   track_buffer->startFrame = sector;
412   dwStatus = ReadCDAudioLBA( hCD, track_buffer );
413 
414   if ( dwStatus == SS_COMP )
415     {
416       return 0;
417     }
418   else
419     {
420       Log( "Error (%d:%d)\n", GetAspiLibError(), GetAspiLibAspiError() );
421       return GetAspiLibAspiError();
422     }
423 
424 }
425 
426 int init_akrip()
427 {
428   static CDLIST cdlist;
429   GETCDHAND cdh;
430   HCDROM hCD;
431 
432   int cd_index, track_index, prefered_cd_index, read_toc_result;
433 
434   prefered_cd_index = -1;
435 
436   if (akrip_init)
437     {
438 	    Log("Avoiding akrip_init to be called another time\n");
439 
440 			if (handle_CD != -1)
441 				CloseCDHandle(handle_CD);
442     }
443   else
444 	  {
445 			akrip_init = 1;
446 
447 		#if defined(CD_DEBUG)
448 			Log("Entering init_akrip()\n");
449 		#endif
450 
451 			ZeroMemory( &cdlist, sizeof(cdlist) );
452 
453 			cdlist.max = MAXCDLIST;
454 
455 			// Check the available cd drives
456 			GetCDList( &cdlist );
457 		}
458 
459   handle_CD = (HCDROM) -1;
460 
461   if ( cdlist.num < 1)
462     {
463 #if defined(CD_DEBUG)
464       Log("No cd drive available\n");
465 #endif
466       return 1;
467     }
468   else
469     {
470 #if defined(CD_DEBUG)
471 	  Log("%d drive(s) found\n", cdlist.num);
472 	  for (cd_index = 0; cd_index < cdlist.num; cd_index++)
473 	    {
474 		  Log("Drive #%d (%d:%d:%d)\n", cd_index, cdlist.cd[cd_index].ha, cdlist.cd[cd_index].tgt, cdlist.cd[cd_index].lun);
475 		}
476 #endif
477 	}
478 
479   track_buffer = NewTrackBuf( 1 );
480 
481   for ( cd_index = 0; (cd_index < cdlist.num) && (prefered_cd_index == -1); cd_index++ )
482     {
483 
484       ZeroMemory( &cdh, sizeof(cdh) );
485       cdh.size     = sizeof(GETCDHAND);
486       cdh.ver      = 1;
487       cdh.ha       = cdlist.cd[cd_index].ha;
488       cdh.tgt      = cdlist.cd[cd_index].tgt;
489       cdh.lun      = cdlist.cd[cd_index].lun;
490       cdh.readType  = CDR_ANY;      // set for autodetect
491 
492 #if defined(CD_DEBUG)
493 	  Log("Trying to test cd (%d:%d:%d)\n", cdh.ha, cdh.tgt, cdh.lun);
494 #endif
495 
496       hCD = GetCDHandle( &cdh);
497 
498       ModifyCDParms( hCD, CDP_MSF, FALSE );
499       if ( read_toc_result = ReadTOC( hCD, &toc ) != SS_COMP )
500         {
501 #if defined(CD_DEBUG)
502           Log( "Error reading TOC (%d)\n", read_toc_result );
503 #endif
504           CloseCDHandle( hCD );
505     	  continue;
506         }
507 #if defined(CD_DEBUG)
508 	  Log("%d tracks on this CD (%d - %d)\n", 1 + toc.lastTrack - toc.firstTrack, toc.firstTrack, toc.lastTrack);
509 #endif
510 
511       for (track_index = 0; track_index <= toc.lastTrack - toc.firstTrack; track_index++)
512         {
513 					#warning disabled code track checking
514 					/*
515           if (toc.tracks[track_index].ADR & 0X04)
516 					*/
517             {
518 	          DWORD addr;
519  	          MSB2DWORD( &addr, toc.tracks[track_index].addr );
520 #if defined(CD_DEBUG)
521 			  Log("Found a code track (#%d, LBA %d)\n", track_index, addr);
522 #endif
523               akrip_read(hCD, addr);
524 	          // Add detection of signature for easiness of use
525 
526 	          prefered_cd_index = cd_index;
527 
528 	          break;
529             }
530 
531         }
532 
533 #if defined(CD_DEBUG)
534 	  Log("Closing handle for this drive\n");
535 #endif
536 
537       CloseCDHandle ( hCD );
538 
539     }
540 
541     if (prefered_cd_index != -1)
542       {
543 
544 		DWORD play_track_result;
545 
546         ZeroMemory( &cdh, sizeof(cdh) );
547         cdh.size     = sizeof(GETCDHAND);
548         cdh.ver      = 1;
549         cdh.ha       = cdlist.cd[prefered_cd_index].ha;
550         cdh.tgt      = cdlist.cd[prefered_cd_index].tgt;
551         cdh.lun      = cdlist.cd[prefered_cd_index].lun;
552         cdh.readType  = CDR_ANY;      // set for autodetect
553 
554 #if defined(CD_DEBUG)
555 		Log("Prefered CD drive #%d (%d:%d:%d)\n", prefered_cd_index, cdh.ha, cdh.tgt, cdh.lun);
556 #endif
557 
558         handle_CD = GetCDHandle( &cdh );
559 
560         ModifyCDParms( handle_CD, CDP_MSF, FALSE );
561         if ( read_toc_result = ReadTOC( handle_CD, &toc ) != SS_COMP )
562           {
563 #if defined(CD_DEBUG)
564             Log( "Error reading TOC (%d)\n", read_toc_result);
565 #endif
566             CloseCDHandle( handle_CD );
567     	    return 1;
568           }
569 	      return (handle_CD >= 0 ? 0 : 1);
570       }
571 
572     return 2;
573 }
574 
575 void shut_akrip()
576 {
577   CloseCDHandle ( handle_CD );
578 }
579 
580 int osd_cd_init( char* dummy )
581 {
582   return init_akrip();
583 }
584 
585 void osd_cd_close()
586 {
587   osd_cd_stop_audio();
588 	shut_akrip();
589 }
590 
591 void osd_cd_read(UChar* p, UInt32 sector)
592 {
593   if (akrip_read( handle_CD, sector ) == 0)
594 		{
595 			memcpy(p, track_buffer->buf + 16 , 2048);
596 			return;
597 		}
598 	Log("Error reading cd sector %d at %s - %d\n", sector, __FILE__, __LINE__);
599   return;
600 
601 }
602 
603 
604 void MSB2DWORD( DWORD *d, BYTE *b )
605 {
606   DWORD retVal;
607 
608   retVal = (DWORD)b[0];
609   retVal = (retVal<<8) + (DWORD)b[1];
610   retVal = (retVal<<8) + (DWORD)b[2];
611   retVal = (retVal<<8) + (DWORD)b[3];
612 
613   *d = retVal;
614 }
615 
616 void osd_cd_nb_tracks(int* first,
617 		      int* last)
618 {
619  *first = toc.firstTrack;
620  *last = toc.lastTrack;
621 }
622 
623 void osd_cd_track_info( UChar track,
624 			int* min,
625 			int* sec,
626 			int* fra,
627 			int* control)
628 {
629  DWORD frame;
630 
631 #if defined(CD_DEBUG)
632  Log("Looking for track info of #%d - %s %d\n", track, __FILE__, __LINE__);
633 #endif
634 
635  track -= toc.firstTrack;
636 
637  *control = ((TOCTRACK)(toc.tracks[track])).ADR;
638 
639  MSB2DWORD( &frame, ((TOCTRACK)(toc.tracks[track])).addr );
640 
641  Frame2Time(frame + 150, min, sec, fra);
642 
643 #if defined(CD_DEBUG)
644  Log("Track begins at frame %d\n", frame + 150);
645 #endif
646 
647 }
648 
649 LPTRACKBUF NewTrackBuf( DWORD numFrames )
650 {
651   LPTRACKBUF t;
652   int numAlloc;
653 
654   numAlloc = (((int)numFrames)*2352) + TRACKBUFEXTRA;
655 
656   t = (LPTRACKBUF)GlobalAlloc( GPTR, numAlloc );
657 
658   if ( !t )
659     return NULL;
660 
661   t->startFrame = 0;
662   t->numFrames = 0;
663   t->maxLen = numFrames * 2352;
664   t->len = 0;
665   t->status = 0;
666   t->startOffset = 0;
667 
668   return t;
669 }
670 
671 void osd_cd_length(int* min,
672                    int* sec,
673                    int* fra)
674 {
675   int index;
676 	DWORD cd_length;
677 
678 #if defined(CD_DEBUG)
679 	Log("Length of CD asked\n");
680 #endif
681 
682 	/*
683 	for ( index = toc.firstTrack; index <= toc.lastTrack; index ++ )
684 		{
685 			cd_length += toc.tracks[index].trackLen;
686 #if defined(CD_DEBUG)
687 			Log("Adding length of track #%d which is %d frames long\n", index, toc.tracks[index].trackLen);
688 #endif
689 		}
690 	*/
691 
692 #warning It s an unprecise heuristic
693 
694 	MSB2DWORD( &cd_length, toc.tracks[toc.lastTrack].addr);
695 
696 #if defined(CD_DEBUG)
697 	Log("Total cd length : %d frames\n", cd_length);
698 #endif
699 
700 	Frame2Time(cd_length,min,sec,fra);
701 }
702 
703 void osd_cd_play_audio_track(UChar track)
704 {
705 	UChar real_track;
706 	UChar min_from, sec_from, fra_from;
707 	UChar min_to, sec_to, fra_to;
708 	DWORD cd_begin, cd_end;
709 
710 #if defined(CD_DEBUG)
711 	Log("Playing track #%d\n", track);
712 #endif
713 
714 	if (track >= toc.lastTrack)
715 		{
716 			Log("Trying to play the last track, abording\n");
717 			return;
718 		}
719 
720 	real_track = track - toc.firstTrack;
721 
722 	MSB2DWORD( &cd_begin, toc.tracks[real_track].addr);
723 
724 	MSB2DWORD( &cd_end, toc.tracks[real_track+1].addr);
725 
726 	fra_from = cd_begin % 75;
727 	cd_begin /= 75;
728 
729 	sec_from = cd_begin % 60;
730 	cd_begin /= 60;
731 
732 	min_from = cd_begin;
733 
734 
735 	fra_to = cd_end % 75;
736 	cd_end /= 75;
737 
738 	sec_to = cd_end % 60;
739 	cd_end /= 60;
740 
741 	min_to = cd_end;
742 
743 	osd_cd_play_audio_range( min_from, sec_from, fra_from, min_to, sec_to, fra_to);
744 
745 }
746 
747 void osd_cd_play_audio_range(
748 			     UChar min_from,
749 			     UChar sec_from,
750 			     UChar fra_from,
751 			     UChar min_to,
752 			     UChar sec_to,
753 			     UChar fra_to)
754 {
755 	DWORD begin, end, length;
756 
757 #if defined(CD_DEBUG)
758 	Log("Playing from %02d:%02d:%02d to %02d:%02d:%02d\n", min_from, sec_from, fra_from,
759 				min_to, sec_to, fra_to);
760 #endif
761 
762 	begin = ((min_from * 60) + sec_from) * 75 + fra_from;
763 
764 	end = ((min_to * 60) + sec_to) * 75 + fra_to;
765 
766 	length = end - begin;
767 
768 	begin -= 150;
769 
770 #if defined(CD_DEBUG)
771 	Log("Playing from frame %d while %d frames\n", begin, length);
772 #endif
773 
774 	PlayAudioRange( handle_CD, begin, length);
775 
776 }
777 
778 void osd_cd_subchannel_info(unsigned short offset)
779 {
780       Wr6502(offset, 4);
781 }
782 
783 
784 void osd_cd_status(int *status)
785 {
786       *status = 0;
787 }
788 
789 void osd_cd_pause(void)
790 {
791 	pauseResumeCD( handle_CD, 1);
792 }
793 
794 void osd_cd_resume(void)
795 {
796 	pauseResumeCD( handle_CD, 0);
797 }
798 
799 void osd_cd_stop_audio()
800 {
801 	startStopUnit( handle_CD, 0, 0);
802 }
803 #endif
804