3 * Cdrom - device driver emulation - Audio features.
4 * (c) 1998 Petr Tomasek <tomasek@etf.cuni.cz>
12 #include <sys/ioctl.h>
13 #include <sys/types.h>
14 /* FIXME - how to make this OS independent ?? */
15 #ifdef HAVE_LINUX_CDROM_H
16 # include <linux/cdrom.h>
18 #ifdef HAVE_LINUX_UCDROM_H
19 # include <linux/ucdrom.h>
30 /* FIXME - more general ?? */
31 #define cdrom_dev "/dev/cdrom"
33 u_char
cdrom_a_status (int fd
)
35 struct cdrom_subchnl sc
;
37 ioctl(fd
,CDROMSUBCHNL
,&sc
);
38 return sc
.cdsc_audiostatus
;
41 BYTE
* get_io_stru (WORD
* reqh
,int dorealmode
)
45 ofst
= reqh
[7]; segm
= reqh
[8];
48 io_stru
= DOSMEM_MapRealToLinear (MAKELONG(ofst
,segm
));
50 io_stru
= PTR_SEG_OFF_TO_LIN(segm
,ofst
);
55 DWORD
msf0_to_abs (struct cdrom_msf0 msf
)
57 return (msf
.minute
*60 +
62 void abs_to_msf0 (DWORD abs
, struct cdrom_msf0
* msf
)
66 msf
->frame
=d
%75; d
=d
/75;
67 msf
->second
=d
%60; msf
->minute
=d
/60;
70 void msf0_to_msf (struct cdrom_msf0 from
, struct cdrom_msf0 to
, struct cdrom_msf
* msf
)
72 msf
->cdmsf_min0
=from
.minute
;
73 msf
->cdmsf_min1
=to
.minute
;
74 msf
->cdmsf_sec0
=from
.second
;
75 msf
->cdmsf_sec1
=to
.second
;
76 msf
->cdmsf_frame0
=from
.frame
;
77 msf
->cdmsf_frame1
=to
.frame
;
80 void abs_to_msf (DWORD from
, DWORD to
, struct cdrom_msf
* msf
)
82 struct cdrom_msf0 fr
,tt
;
83 abs_to_msf0(from
, &fr
);
85 msf0_to_msf(fr
,tt
,msf
);
88 /************************************************************
90 * Cdrom ms-dos driver emulation.
91 * (accesible throught the MSCDEX 0x10 function.)
94 extern void do_mscdex_dd (CONTEXT
* context
, int dorealmode
)
96 BYTE
* driver_request
;
98 static int fdcd
=-1; /* file descriptor.. */
99 struct cdrom_tochdr tochdr
; /* the Toc header */
100 struct cdrom_tocentry tocentry
; /* a Toc entry */
101 struct cdrom_msf msf
;
102 struct cdrom_subchnl subchnl
;
103 u_char Error
=255; /*No Error */
106 driver_request
=DOSMEM_MapRealToLinear
107 (MAKELONG(BX_reg(context
),ES_reg(context
)));
109 driver_request
=PTR_SEG_OFF_TO_LIN(ES_reg(context
),BX_reg(context
));
112 { /* FIXME - to be deleted ?? */
113 ERR(int," ES:BX==0 ! SEGFAULT ?\n");
114 ERR(int," -->BX=0x%04x, ES=0x%04lx, DS=0x%04lx, CX=0x%04x\n\n",
122 /* FIXME - would be best to open the device at the begining of the wine
124 if (fdcd
<0) fdcd
=open(cdrom_dev
,O_RDONLY
);
126 TRACE(int,"CDROM device driver -> command <%d>\n",
127 (unsigned char)driver_request
[2]);
129 /* set status to 0 */
134 switch(driver_request
[2])
137 io_stru
=get_io_stru((WORD
*)driver_request
,dorealmode
);
138 FIXME(int," --> IOCTL INPUT <%d>\n",io_stru
[0]);
141 case 1: /* location of head */
144 ioctl(fdcd
,CDROMSUBCHNL
,&subchnl
);
145 ((DWORD
*)io_stru
+2)[0]=(DWORD
)msf0_to_abs(subchnl
.cdsc_absaddr
.msf
);
146 FIXME(int," ----> HEAD LOCATION <%ld>\n\n",
147 ((DWORD
*)io_stru
+2)[0]);
151 ERR(int,"CDRom-Driver: Unsupported address mode !!\n");
156 case 6: /* device status */
157 /* FIXME .. does this work properly ?? */
158 io_stru
[3]=io_stru
[4]=0;
159 io_stru
[2]=1; /* supports audio channels (?? FIXME ??) */
160 io_stru
[1]=16; /* data read and plays audio racks */
161 #if defined(CDROM_DRIVE_STATUS) && defined(CDS_TRAY_OPEN)
162 io_stru
[1]|=(ioctl(fdcd
,CDROM_DRIVE_STATUS
,0)==CDS_TRAY_OPEN
);
164 TRACE(int," ----> DEVICE STATUS <0x%08lx>\n\n",(DWORD
)io_stru
[1]);
167 case 9: /* media changed ? */
168 #ifdef CDROM_MEDIA_CHANGED
169 if (ioctl(fdcd
,CDROM_MEDIA_CHANGED
,0))
173 io_stru
[0]=0; /* FIXME? 1? */
176 case 10: /* audio disk info */
177 ioctl(fdcd
,CDROMREADTOCHDR
,&tochdr
);
178 io_stru
[1]=tochdr
.cdth_trk0
; /* staring track of the disc */
179 io_stru
[2]=tochdr
.cdth_trk1
; /* ending track */
180 tocentry
.cdte_track
=CDROM_LEADOUT
; /* Now the leadout track ...*/
181 tocentry
.cdte_format
=CDROM_MSF
;
182 ioctl(fdcd
,CDROMREADTOCENTRY
,&tocentry
); /* ... get position of it */
183 ((DWORD
*)io_stru
+3)[0]=(DWORD
)msf0_to_abs(tocentry
.cdte_addr
.msf
);
184 TRACE(int," ----> AUDIO DISK INFO <%d-%d/%ld>\n\n",
185 io_stru
[1],io_stru
[2],
186 ((DWORD
*)io_stru
+3)[0]);
190 case 11: /* audio track info */
191 tocentry
.cdte_track
=io_stru
[1]; /* track of the disc */
192 tocentry
.cdte_format
=CDROM_MSF
;
193 ioctl(fdcd
,CDROMREADTOCENTRY
,&tocentry
);
194 ((DWORD
*)io_stru
+2)[0]=(DWORD
)msf0_to_abs(tocentry
.cdte_addr
.msf
);
195 /* starting point if the track */
196 io_stru
[6]=tocentry
.cdte_adr
+16*tocentry
.cdte_ctrl
;
197 TRACE(int," ----> AUDIO TRACK INFO <track=%d>[%ld] \n\n",
198 io_stru
[1],((DWORD
*)io_stru
+2)[0]);
201 case 12: /* get Q-Channel / Subchannel (??) info */
202 subchnl
.cdsc_format
=CDROM_MSF
;
203 ioctl(fdcd
,CDROMSUBCHNL
,&subchnl
);
204 io_stru
[1]=subchnl
.cdsc_adr
+16*subchnl
.cdsc_ctrl
;
205 io_stru
[2]=subchnl
.cdsc_trk
;
206 io_stru
[3]=subchnl
.cdsc_ind
; /* FIXME - ?? */
207 io_stru
[4]=subchnl
.cdsc_reladdr
.msf
.minute
;
208 io_stru
[5]=subchnl
.cdsc_reladdr
.msf
.second
;
209 io_stru
[6]=subchnl
.cdsc_reladdr
.msf
.frame
;
210 io_stru
[7]=0; /* always zero */
211 io_stru
[8]=subchnl
.cdsc_absaddr
.msf
.minute
;
212 io_stru
[9]=subchnl
.cdsc_absaddr
.msf
.second
;
213 io_stru
[10]=subchnl
.cdsc_absaddr
.msf
.frame
;
216 case 15: /* fixme !!!!!!! just a small workaround ! */
217 /* !!!! FIXME FIXME FIXME !! */
218 tocentry
.cdte_track
=CDROM_LEADOUT
; /* Now the leadout track ...*/
219 tocentry
.cdte_format
=CDROM_MSF
;
220 ioctl(fdcd
,CDROMREADTOCENTRY
,&tocentry
); /* ... get position of it */
221 ((DWORD
*)io_stru
+7)[0]=(DWORD
)msf0_to_abs(tocentry
.cdte_addr
.msf
);
225 FIXME(int," Cdrom-driver: IOCTL INPUT: Unimplemented <%d>!! \n",
233 io_stru
=get_io_stru((WORD
*)driver_request
,dorealmode
);
234 TRACE(int," --> IOCTL OUTPUT <%d>\n",io_stru
[0]);
238 ioctl (fdcd
,CDROMEJECT
);
239 TRACE(int," ----> EJECT \n\n");
241 case 5: /* close tray */
242 ioctl (fdcd
,CDROMCLOSETRAY
);
243 TRACE(int," ----> CLOSE TRAY \n\n");
245 case 2: /* reset drive */
246 ioctl (fdcd
,CDROMRESET
);
247 TRACE(int," ----> RESET \n\n");
250 FIXME(int," Cdrom-driver: IOCTL OUPUT: Unimplemented <%d>!! \n",
258 if (cdrom_a_status(fdcd
)==CDROM_AUDIO_PLAY
)
260 ioctl (fdcd
,CDROMPAUSE
);
261 TRACE(int," --> STOP AUDIO (Paused)\n\n");
265 ioctl (fdcd
,CDROMSTOP
);
266 TRACE(int," --> STOP AUDIO (Stopped)\n\n");
270 case 132: /* FIXME - It didn't function for me... */
271 FIXME(int," --> PLAY AUDIO \n");
272 ioctl (fdcd
,CDROMSTART
);
273 FIXME(int,"Mode :<0x%02X> , [%ld-%ld]\n\n",
274 (unsigned char)driver_request
[13],
275 ((DWORD
*)driver_request
+14)[0],
276 ((DWORD
*)driver_request
+18)[0]);
277 if (driver_request
[13]==0)
279 abs_to_msf(((DWORD
*)driver_request
+14)[0],
280 ((DWORD
*)driver_request
+18)[0],&msf
);
281 ioctl(fdcd
,CDROMPLAYMSF
,&msf
);
285 ERR(int,"CDRom-Driver: Unsupported address mode !!\n");
290 TRACE(int," --> RESUME AUDIO \n\n");
291 ioctl(fdcd
,CDROMRESUME
);
294 FIXME(int," CDRom-Driver - ioctl uninplemented <%d>\n",driver_request
[2]);
301 driver_request
[4]|=127;
302 driver_request
[3]=Error
;
304 driver_request
[4]|=2*(cdrom_a_status(fdcd
)==CDROM_AUDIO_PLAY
);
306 /* close (fdcd); FIXME !! -- cannot use close when ejecting
307 the cd-rom - close would close it again */