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