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>
27 /* #define DEBUG_INT */
31 /* FIXME - more general ?? */
32 #define cdrom_dev "/dev/cdrom"
34 u_char
cdrom_a_status (int fd
)
36 struct cdrom_subchnl sc
;
38 ioctl(fd
,CDROMSUBCHNL
,&sc
);
39 return sc
.cdsc_audiostatus
;
42 BYTE
* get_io_stru (WORD
* reqh
,int dorealmode
)
46 ofst
= reqh
[7]; segm
= reqh
[8];
49 io_stru
= DOSMEM_MapRealToLinear (MAKELONG(ofst
,segm
));
51 io_stru
= PTR_SEG_OFF_TO_LIN(segm
,ofst
);
56 DWORD
msf0_to_abs (struct cdrom_msf0 msf
)
58 return (msf
.minute
*60 +
63 void abs_to_msf0 (DWORD abs
, struct cdrom_msf0
* msf
)
67 msf
->frame
=d
%75; d
=d
/75;
68 msf
->second
=d
%60; msf
->minute
=d
/60;
71 void msf0_to_msf (struct cdrom_msf0 from
, struct cdrom_msf0 to
, struct cdrom_msf
* msf
)
73 msf
->cdmsf_min0
=from
.minute
;
74 msf
->cdmsf_min1
=to
.minute
;
75 msf
->cdmsf_sec0
=from
.second
;
76 msf
->cdmsf_sec1
=to
.second
;
77 msf
->cdmsf_frame0
=from
.frame
;
78 msf
->cdmsf_frame1
=to
.frame
;
81 void abs_to_msf (DWORD from
, DWORD to
, struct cdrom_msf
* msf
)
83 struct cdrom_msf0 fr
,tt
;
84 abs_to_msf0(from
, &fr
);
86 msf0_to_msf(fr
,tt
,msf
);
89 /************************************************************
91 * Cdrom ms-dos driver emulation.
92 * (accesible throught the MSCDEX 0x10 function.)
95 extern void do_mscdex_dd (CONTEXT
* context
, int dorealmode
)
97 BYTE
* driver_request
;
99 static int fdcd
=-1; /* file descriptor.. */
100 struct cdrom_tochdr tochdr
; /* the Toc header */
101 struct cdrom_tocentry tocentry
; /* a Toc entry */
102 struct cdrom_msf msf
;
103 struct cdrom_subchnl subchnl
;
104 u_char Error
=255; /*No Error */
107 driver_request
=DOSMEM_MapRealToLinear
108 (MAKELONG(BX_reg(context
),ES_reg(context
)));
110 driver_request
=PTR_SEG_OFF_TO_LIN(ES_reg(context
),BX_reg(context
));
113 { /* FIXME - to be deleted ?? */
114 ERR(int," ES:BX==0 ! SEGFAULT ?\n");
115 ERR(int," -->BX=0x%04x, ES=0x%04lx, DS=0x%04lx, CX=0x%04x\n\n",
123 /* FIXME - would be best to open the device at the begining of the wine
125 if (fdcd
<0) fdcd
=open(cdrom_dev
,O_RDONLY
);
127 TRACE(int,"CDROM device driver -> command <%d>\n",
128 (unsigned char)driver_request
[2]);
130 /* set status to 0 */
135 switch(driver_request
[2])
138 io_stru
=get_io_stru((WORD
*)driver_request
,dorealmode
);
139 FIXME(int," --> IOCTL INPUT <%d>\n",io_stru
[0]);
142 case 1: /* location of head */
145 ioctl(fdcd
,CDROMSUBCHNL
,&subchnl
);
146 ((DWORD
*)io_stru
+2)[0]=(DWORD
)msf0_to_abs(subchnl
.cdsc_absaddr
.msf
);
147 FIXME(int," ----> HEAD LOCATION <%ld>\n\n",
148 ((DWORD
*)io_stru
+2)[0]);
152 ERR(int,"CDRom-Driver: Unsupported address mode !!\n");
157 case 6: /* device status */
158 /* FIXME .. does this work properly ?? */
159 io_stru
[3]=io_stru
[4]=0;
160 io_stru
[2]=1; /* supports audio channels (?? FIXME ??) */
161 io_stru
[1]=16; /* data read and plays audio racks */
162 io_stru
[1]|=(ioctl(fdcd
,CDROM_DRIVE_STATUS
,0)==CDS_TRAY_OPEN
);
163 TRACE(int," ----> DEVICE STATUS <0x%08lx>\n\n",(DWORD
)io_stru
[1]);
166 case 9: /* media changed ? */
167 if (ioctl(fdcd
,CDROM_MEDIA_CHANGED
,0))
170 io_stru
[0]=0; /* FIXME? 1? */
173 case 10: /* audio disk info */
174 ioctl(fdcd
,CDROMREADTOCHDR
,&tochdr
);
175 io_stru
[1]=tochdr
.cdth_trk0
; /* staring track of the disc */
176 io_stru
[2]=tochdr
.cdth_trk1
; /* ending track */
177 tocentry
.cdte_track
=CDROM_LEADOUT
; /* Now the leadout track ...*/
178 tocentry
.cdte_format
=CDROM_MSF
;
179 ioctl(fdcd
,CDROMREADTOCENTRY
,&tocentry
); /* ... get position of it */
180 ((DWORD
*)io_stru
+3)[0]=(DWORD
)msf0_to_abs(tocentry
.cdte_addr
.msf
);
181 TRACE(int," ----> AUDIO DISK INFO <%d-%d/%ld>\n\n",
182 io_stru
[1],io_stru
[2],
183 ((DWORD
*)io_stru
+3)[0]);
187 case 11: /* audio track info */
188 tocentry
.cdte_track
=io_stru
[1]; /* track of the disc */
189 tocentry
.cdte_format
=CDROM_MSF
;
190 ioctl(fdcd
,CDROMREADTOCENTRY
,&tocentry
);
191 ((DWORD
*)io_stru
+2)[0]=(DWORD
)msf0_to_abs(tocentry
.cdte_addr
.msf
);
192 /* starting point if the track */
193 io_stru
[6]=tocentry
.cdte_adr
+16*tocentry
.cdte_ctrl
;
194 TRACE(int," ----> AUDIO TRACK INFO <track=%d>[%ld] \n\n",
195 io_stru
[1],((DWORD
*)io_stru
+2)[0]);
198 case 12: /* get Q-Channel / Subchannel (??) info */
199 subchnl
.cdsc_format
=CDROM_MSF
;
200 ioctl(fdcd
,CDROMSUBCHNL
,&subchnl
);
201 io_stru
[1]=subchnl
.cdsc_adr
+16*subchnl
.cdsc_ctrl
;
202 io_stru
[2]=subchnl
.cdsc_trk
;
203 io_stru
[3]=subchnl
.cdsc_ind
; /* FIXME - ?? */
204 io_stru
[4]=subchnl
.cdsc_reladdr
.msf
.minute
;
205 io_stru
[5]=subchnl
.cdsc_reladdr
.msf
.second
;
206 io_stru
[6]=subchnl
.cdsc_reladdr
.msf
.frame
;
207 io_stru
[7]=0; /* always zero */
208 io_stru
[8]=subchnl
.cdsc_absaddr
.msf
.minute
;
209 io_stru
[9]=subchnl
.cdsc_absaddr
.msf
.second
;
210 io_stru
[10]=subchnl
.cdsc_absaddr
.msf
.frame
;
213 case 15: /* fixme !!!!!!! just a small workaround ! */
214 /* !!!! FIXME FIXME FIXME !! */
215 tocentry
.cdte_track
=CDROM_LEADOUT
; /* Now the leadout track ...*/
216 tocentry
.cdte_format
=CDROM_MSF
;
217 ioctl(fdcd
,CDROMREADTOCENTRY
,&tocentry
); /* ... get position of it */
218 ((DWORD
*)io_stru
+7)[0]=(DWORD
)msf0_to_abs(tocentry
.cdte_addr
.msf
);
222 FIXME(int," Cdrom-driver: IOCTL INPUT: Unimplemented <%d>!! \n",
230 io_stru
=get_io_stru((WORD
*)driver_request
,dorealmode
);
231 TRACE(int," --> IOCTL OUTPUT <%d>\n",io_stru
[0]);
235 ioctl (fdcd
,CDROMEJECT
);
236 TRACE(int," ----> EJECT \n\n");
238 case 5: /* close tray */
239 ioctl (fdcd
,CDROMCLOSETRAY
);
240 TRACE(int," ----> CLOSE TRAY \n\n");
242 case 2: /* reset drive */
243 ioctl (fdcd
,CDROMRESET
);
244 TRACE(int," ----> RESET \n\n");
247 FIXME(int," Cdrom-driver: IOCTL OUPUT: Unimplemented <%d>!! \n",
255 if (cdrom_a_status(fdcd
)==CDROM_AUDIO_PLAY
)
257 ioctl (fdcd
,CDROMPAUSE
);
258 TRACE(int," --> STOP AUDIO (Paused)\n\n");
262 ioctl (fdcd
,CDROMSTOP
);
263 TRACE(int," --> STOP AUDIO (Stopped)\n\n");
267 case 132: /* FIXME - It didn't function for me... */
268 FIXME(int," --> PLAY AUDIO \n");
269 ioctl (fdcd
,CDROMSTART
);
270 FIXME(int,"Mode :<0x%02X> , [%ld-%ld]\n\n",
271 (unsigned char)driver_request
[13],
272 ((DWORD
*)driver_request
+14)[0],
273 ((DWORD
*)driver_request
+18)[0]);
274 if (driver_request
[13]==0)
276 abs_to_msf(((DWORD
*)driver_request
+14)[0],
277 ((DWORD
*)driver_request
+18)[0],&msf
);
278 ioctl(fdcd
,CDROMPLAYMSF
,&msf
);
282 ERR(int,"CDRom-Driver: Unsupported address mode !!\n");
287 TRACE(int," --> RESUME AUDIO \n\n");
288 ioctl(fdcd
,CDROMRESUME
);
291 FIXME(int," CDRom-Driver - ioctl uninplemented <%d>\n",driver_request
[2]);
298 driver_request
[4]|=127;
299 driver_request
[3]=Error
;
301 driver_request
[4]|=2*(cdrom_a_status(fdcd
)==CDROM_AUDIO_PLAY
);
303 /* close (fdcd); FIXME !! -- cannot use close when ejecting
304 the cd-rom - close would close it again */