1 #include <sys/types.h>
2 #include <unistd.h>
3 #include <string.h>
4 #include "osd_linux_cd.h"
5 #include "utils.h"
6 #include "hard_pce.h"
7 
8 int cd_drive_handle = 0;
9 
10 
osd_cd_init(char * device)11 int osd_cd_init(char *device)
12 {
13   Log("Init linux cdrom device\n");
14 
15   if (strcmp(device, ""))
16     cd_drive_handle = open(device, O_RDONLY | O_NONBLOCK);
17   else
18     cd_drive_handle = open("/dev/cdrom", O_RDONLY | O_NONBLOCK);
19 
20   return (cd_drive_handle == 0);
21 }
22 
23 
osd_cd_stop_audio()24 void osd_cd_stop_audio()
25 {
26   if (ioctl(cd_drive_handle, CDROMSTOP) == -1)
27     perror("osd_cd_stop_audio");
28 }
29 
30 
osd_cd_close()31 void osd_cd_close()
32 {
33   osd_cd_stop_audio();
34   close(cd_drive_handle);
35 }
36 
37 
osd_cd_read(UChar * p,UInt32 sector)38 void osd_cd_read(UChar *p, UInt32 sector)
39 {
40   int retries = 0;
41   char buf[128];
42 
43   while ((lseek(cd_drive_handle, 2048 * sector, SEEK_SET) < 0) && (retries < 3)) {
44     sprintf(buf, "osd_cd_read:lseek (sector=%d, retry=%d)", sector, retries);
45     perror(buf);
46     retries++;
47   }
48 
49   while ((read(cd_drive_handle, p, 2048) < 0) && (retries++ < 3)) {
50     sprintf(buf, "osd_cd_read:read (sector=%d, retry=%d)", sector, retries);
51     perror(buf);
52   }
53 }
54 
55 extern unsigned char binbcd[];
56 
osd_cd_subchannel_info(unsigned short offset)57 void osd_cd_subchannel_info(unsigned short offset)
58 {
59   struct cdrom_subchnl subc;
60 
61   subc.cdsc_format = CDROM_MSF;
62 
63   if (ioctl(cd_drive_handle, CDROMSUBCHNL, &subc) == -1)
64     perror("osd_cd_subchannel_info");
65 
66 /*
67   switch(subc.cdsc_audiostatus) {
68     case CDROM_AUDIO_PLAY:
69       put_8bit_addr(offset, 0);
70       break;
71     case CDROM_AUDIO_PAUSED:
72       put_8bit_addr(offset, 1);
73       break;
74     case CDROM_AUDIO_COMPLETED:
75       put_8bit_addr(offset, 3);
76       break;
77     default:
78       put_8bit_addr(offset, 4);
79       break;
80   }
81 */
82 
83   Wr6502(offset, subc.cdsc_audiostatus - 0x11);
84 
85   Wr6502(offset + 1, subc.cdsc_ctrl);
86   Wr6502(offset + 2, binbcd[subc.cdsc_trk]);
87   Wr6502(offset + 3, binbcd[subc.cdsc_ind]);
88   Wr6502(offset + 4, binbcd[subc.cdsc_reladdr.msf.minute]);
89   Wr6502(offset + 5, binbcd[subc.cdsc_reladdr.msf.second]);
90   Wr6502(offset + 6, binbcd[subc.cdsc_reladdr.msf.frame]);
91   Wr6502(offset + 7, binbcd[subc.cdsc_absaddr.msf.minute]);
92   Wr6502(offset + 8, binbcd[subc.cdsc_absaddr.msf.second]);
93   Wr6502(offset + 9, binbcd[subc.cdsc_absaddr.msf.frame]);
94 }
95 
96 
osd_cd_status(int * status)97 void osd_cd_status(int *status)
98 {
99   struct cdrom_subchnl subc;
100 
101   subc.cdsc_format = CDROM_MSF;
102 
103   if (ioctl(cd_drive_handle, CDROMSUBCHNL, &subc) == -1)
104     perror("osd_cd_status");
105 
106   *status = subc.cdsc_audiostatus - 0x10;
107 //  switch(subc.cdsc_audiostatus) {
108 //    case CDROM_AUDIO_PLAY:
109 //      *status = 1;
110 //      break;
111 //    default:
112 //      *status = subc.cdsc_audiostatus;
113 //      break;
114 //  }
115 
116 }
117 
118 
osd_cd_track_info(UChar track,int * min,int * sec,int * fra,int * control)119 void osd_cd_track_info(UChar track, int *min, int *sec, int *fra, int *control)
120 {
121   struct cdrom_tocentry tocentry;
122 
123   tocentry.cdte_track = track;
124   tocentry.cdte_format = CDROM_MSF;
125 
126   if (ioctl(cd_drive_handle, CDROMREADTOCENTRY, &tocentry) == -1)
127     perror("osd_cd_track_info");
128 
129 //  Log("Track %d begins at %d and got command byte of %d\n", track,
130 //      tocentry.cdte_addr.lba + 150, tocentry.cdte_ctrl);
131 
132 //  Frame2Time(tocentry.cdte_addr.lba + 150, min, sec, fra);
133 
134   *min = tocentry.cdte_addr.msf.minute;
135   *sec = tocentry.cdte_addr.msf.second;
136   *fra = tocentry.cdte_addr.msf.frame;
137   *control = tocentry.cdte_ctrl;
138 }
139 
140 
osd_cd_nb_tracks(int * first,int * last)141 void osd_cd_nb_tracks(int *first, int *last)
142 {
143   struct cdrom_tochdr track_info;
144 
145   if (ioctl(cd_drive_handle, CDROMREADTOCHDR, &track_info) == -1)
146     perror("cd_nb_tracks");
147 
148   *first = track_info.cdth_trk0;
149   *last = track_info.cdth_trk1;
150 }
151 
152 
osd_cd_length(int * min,int * sec,int * fra)153 void osd_cd_length(int *min, int *sec, int *fra)
154 {
155   struct cdrom_tocentry toc_info;
156 
157   toc_info.cdte_track = CDROM_LEADOUT;
158   toc_info.cdte_format = CDROM_MSF;
159 
160   if (ioctl(cd_drive_handle, CDROMREADTOCENTRY, &toc_info) == -1)
161     perror("cd_length");
162 
163   *min = toc_info.cdte_addr.msf.minute;
164   *sec = toc_info.cdte_addr.msf.second;
165   *fra = toc_info.cdte_addr.msf.frame;
166 }
167 
168 
osd_cd_pause(void)169 void osd_cd_pause(void)
170 {
171   if (ioctl(cd_drive_handle, CDROMPAUSE) == -1)
172     perror("osd_cd_pause");
173 }
174 
175 
osd_cd_resume(void)176 void osd_cd_resume(void)
177 {
178   if (ioctl(cd_drive_handle, CDROMRESUME) == -1)
179     perror("osd_cd_resume");
180 }
181 
182 
183 /* TODO : check for last track asked */
osd_cd_play_audio_track(UChar track)184 void osd_cd_play_audio_track(UChar track)
185 {
186   struct cdrom_ti cdrom_ti_dat =
187     {
188       track,
189       0,
190       track + 1,
191       0
192     };
193 
194   if (ioctl(cd_drive_handle, CDROMPLAYTRKIND, &cdrom_ti_dat) == -1)
195     perror("play_audio_track");
196 }
197 
198 
osd_cd_play_audio_range(UChar min_from,UChar sec_from,UChar fra_from,UChar min_to,UChar sec_to,UChar fra_to)199 void osd_cd_play_audio_range(UChar min_from, UChar sec_from, UChar fra_from,
200                              UChar min_to, UChar sec_to, UChar fra_to)
201 {
202   struct cdrom_msf cdrom_msf_dat =
203   {
204     min_from,
205     sec_from,
206     fra_from,
207     min_to,
208     sec_to,
209     fra_to
210   };
211 
212   if (ioctl(cd_drive_handle, CDROMPLAYMSF, &cdrom_msf_dat) == -1)
213     perror("play_audio_range");
214 }
215