|
|
1.1 root 1: /***************************************************************************
2: * CDROM.C - CD-ROM interface code (audio routines) *
3: * *
4: ***************************************************************************/
5:
6: #if 0 // old code for CD-ROM detection - doesn't work under Windows '95
7: #include "stdio.h"
8: #include "dos.h"
9: #include "malloc.h"
10: #include "sys\types.h"
11: #include "sys\stat.h"
12: #include "fcntl.h"
13: #include <memcheck.h>
14:
15: #ifdef __386__
16: #define LES_MKFP(s,o) (void far *)(s<<4)
17: #else
18: #define LES_MKFP(s,o) MK_FP(s,o)
19: #endif
20:
21: #define CMDBUFSIZE 22
22:
23: #define IOCMD2 0x4402
24: #define IOCMD3 0x4403
25:
26: //** IOCTL3 commands
27: #define CD_OPENDOORCMD 0x00
28: #define CD_CLOSEDOORCMD 0x05
29: #define CD_RESETCMD 0x02
30:
31: //** IOCTL2 commands
32: #define CD_STATUSCMD 0x06
33:
34: short cddrive,
35: cddrives,
36: cdhdl,
37: cdhitrack,
38: cdlotrack,
39: cdtracktoplay;
40:
41: long leadout;
42:
43: unsigned short bufoff[100],bufseg[100],
44: cmdoff,cmdseg,
45: devoff,devseg,
46: nameoff,nameseg,
47: rmoff,rmseg;
48:
49: char cddevname[9],
50: far *namebuf;
51:
52: char far *cddevadr;
53:
54: struct redbook {
55: char frame;
56: char second;
57: char minute;
58: char unused;
59: char control;
60: } redbook[20];
61:
62: struct rmregs {
63: unsigned long edi,esi,ebp;
64: unsigned long reserved;
65: unsigned long ebx,edx,ecx,eax;
66: unsigned short flags,es,ds,fs,gs,ip,cs,sp,ss;
67: } rmregs;
68:
69: #ifdef __386__
70: void
71: rmint86(short intno,struct rmregs *rmptr)
72: {
73: union REGS regs;
74: struct SREGS sregs;
75:
76: memset(®s,0,sizeof(union REGS));
77: segread(&sregs);
78: regs.x.eax=0x0300;
79: regs.x.ebx=intno;
80: regs.x.ecx=0x0000;
81: sregs.es=FP_SEG(rmptr);
82: regs.x.edi=FP_OFF(rmptr);
83: rmptr->ss=rmptr->sp=0;
84: rmptr->flags=0;
85: int386x(0x31,®s,®s,&sregs);
86: }
87: #else
88: void
89: rmint86(short intno,struct rmregs *rmptr)
90: {
91: union REGS regs;
92: struct SREGS sregs;
93:
94: regs.x.ax=rmptr->eax;
95: regs.x.bx=rmptr->ebx;
96: regs.x.cx=rmptr->ecx;
97: regs.x.dx=rmptr->edx;
98: regs.x.di=rmptr->edi;
99: regs.x.si=rmptr->esi;
100: regs.x.cflag=rmptr->flags;
101: segread(&sregs);
102: if (rmptr->es != 0) {
103: sregs.es=rmptr->es;
104: }
105: if (rmptr->cs != 0) {
106: sregs.cs=rmptr->cs;
107: }
108: if (rmptr->ss != 0) {
109: sregs.ss=rmptr->ss;
110: }
111: if (rmptr->ds != 0) {
112: sregs.ds=rmptr->ds;
113: }
114: int86x(intno,®s,®s,&sregs);
115: rmptr->eax=regs.x.ax;
116: rmptr->ebx=regs.x.bx;
117: rmptr->ecx=regs.x.cx;
118: rmptr->edx=regs.x.dx;
119: rmptr->edi=regs.x.di;
120: rmptr->esi=regs.x.si;
121: rmptr->flags=regs.x.cflag;
122: rmptr->es=sregs.es;
123: rmptr->cs=sregs.cs;
124: rmptr->ss=sregs.ss;
125: rmptr->ds=sregs.ds;
126: }
127: #endif
128:
129: #ifdef __386__
130: void far *
131: alcmem(short bytes)
132: {
133: union REGS regs;
134:
135: regs.x.eax=0x0100;
136: regs.x.ebx=((bytes+16)/16);
137: int386(0x31,®s,®s);
138: if (regs.x.cflag == 0) {
139: rmseg=regs.x.eax;
140: rmoff=0x0000;
141: return((void far *)(rmseg<<4));
142: }
143: return(NULL);
144: }
145: #else
146: void far *
147: alcmem(short bytes)
148: {
149: char far *ptr;
150:
151: ptr=_fmalloc(bytes);
152: rmseg=FP_SEG(ptr);
153: rmoff=FP_OFF(ptr);
154: return(ptr);
155: }
156: #endif
157:
158: int
159: ismscdex(void)
160: {
161: memset(&rmregs,0,sizeof(struct rmregs));
162: rmregs.eax=0x1500;
163: rmregs.ebx=0x0000;
164: rmint86(0x2F,&rmregs);
165: if (rmregs.ebx != 0) {
166: cddrive='A'+rmregs.ecx;
167: return('A'+rmregs.ecx);
168: }
169: return(0);
170: }
171:
172: void
173: cd_getname(void)
174: {
175: if (alcmem(cddrives*5) != NULL) {
176: devseg=rmseg;
177: devoff=rmoff;
178: namebuf=LES_MKFP(devseg,devoff);
179: }
180: memset(&rmregs,0,sizeof(struct rmregs));
181: rmregs.eax=0x1501;
182: rmregs.ebx=devoff;
183: rmregs.es=devseg;
184: rmint86(0x2F,&rmregs);
185: }
186:
187: void
188: sendIOcmd(short hdl,short bytes,short cmd)
189: {
190: memset(&rmregs,0,sizeof(rmregs));
191: rmregs.ebx=hdl;
192: rmregs.ds=cmdseg;
193: rmregs.edx=cmdoff;
194: rmregs.ecx=bytes;
195: rmregs.eax=cmd;
196: rmint86(0x21,&rmregs);
197: }
198:
199: void
200: cd_opendoor(short cdhdl)
201: {
202: char far *ptr;
203:
204: ptr=LES_MKFP(cmdseg,cmdoff);
205: ptr[0]=CD_OPENDOORCMD;
206: sendIOcmd(cdhdl,1,IOCMD3);
207: }
208:
209: void
210: cd_closedoor(short cdhdl)
211: {
212: char far *ptr;
213:
214: ptr=LES_MKFP(cmdseg,cmdoff);
215: ptr[0]=CD_CLOSEDOORCMD;
216: sendIOcmd(cdhdl,1,IOCMD3);
217: }
218:
219: void
220: cd_reset(short cdhdl)
221: {
222: char far *ptr;
223:
224: ptr=LES_MKFP(cmdseg,cmdoff);
225: ptr[0]=CD_RESETCMD;
226: sendIOcmd(cdhdl,1,IOCMD3);
227: }
228:
229: void
230: cd_getaudiodisk(short cdhdl)
231: {
232: int i;
233: char far *ptr;
234:
235: ptr=LES_MKFP(cmdseg,cmdoff);
236: ptr[0]=0x0A;
237: sendIOcmd(cdhdl,8,IOCMD2);
238: cdlotrack=ptr[1];
239: cdhitrack=ptr[2];
240: leadout=ptr[3]+(ptr[4]<<8)+(ptr[5]<<16)+(ptr[6]<<24);
241: }
242:
243: void
244: cd_getaudiotrack(short cdhdl,char tno)
245: {
246: char far *ptr;
247:
248: ptr=LES_MKFP(cmdseg,cmdoff);
249: ptr[0]=0x0B;
250: ptr[1]=tno;
251: sendIOcmd(cdhdl,8,IOCMD2);
252: redbook[tno].frame=ptr[2];
253: redbook[tno].second=ptr[3];
254: redbook[tno].minute=ptr[4];
255: redbook[tno].unused=ptr[5];
256: redbook[tno].control=ptr[6];
257: }
258:
259: int
260: cd_init(void)
261: {
262: int i;
263:
264: if ((cddrives=ismscdex()) == 0) {
265: return(0);
266: }
267: if (alcmem(CMDBUFSIZE) == NULL) {
268: return(0);
269: }
270: cmdseg=rmseg;
271: cmdoff=rmoff;
272: cd_getname();
273: nameseg=(unsigned short)(namebuf[4]<<8)+namebuf[3];
274: nameoff=(unsigned short)(namebuf[2]<<8)+namebuf[1];
275: cddevadr=LES_MKFP(nameseg,nameoff);
276: _fmemmove((char far *)&cddevname,cddevadr+10,8);
277: if ((cdhdl=open(cddevname,O_RDWR)) == -1) {
278: return(0);
279: }
280: cd_reset(cdhdl);
281: cd_getaudiodisk(cdhdl);
282: for (i=cdlotrack ; i <= cdhitrack ; i++) {
283: cd_getaudiotrack(cdhdl,i);
284: }
285: return(1);
286: }
287:
288: void
289: cd_uninit(void)
290: {
291: close(cdhdl);
292: }
293:
294: void
295: cd_stopplay(void)
296: {
297: char far *ptr;
298:
299: ptr=LES_MKFP(cmdseg,cmdoff);
300: memset(ptr,0,CMDBUFSIZE);
301: ptr[0]=0x16;
302: ptr[1]=0x00;
303: ptr[2]=0x85;
304: memset(&rmregs,0,sizeof(struct rmregs));
305: rmregs.es=cmdseg;
306: rmregs.ebx=cmdoff;
307: rmregs.ecx=cddrive-'A';
308: rmregs.eax=0x1510;
309: rmint86(0x2F,&rmregs);
310: }
311:
312: int
313: cd_playtrack(char tno)
314: {
315: char status;
316: long frames,hsgfmt;
317: char far *ptr;
318:
319: if ((redbook[tno].control&0x40) == 0x40) { // don't play data tracks
320: return(0);
321: }
322: cd_stopplay();
323: ptr=LES_MKFP(cmdseg,cmdoff);
324: memset(ptr,0,CMDBUFSIZE);
325: ptr[0]=0x16;
326: ptr[1]=0x00; // sub-unit
327: ptr[2]=0x84; // play-audio command
328: ptr[13]=0x00; // addressing mode
329: hsgfmt=((long)redbook[tno].minute*4500L)+((long)redbook[tno].second*75L)
330: +((long)redbook[tno].frame)-150L;
331: ptr[14]=(char)hsgfmt&0x0FF;
332: ptr[15]=(char)(hsgfmt>>8)&0xFF;
333: ptr[16]=(char)(hsgfmt>>16)&0xFF;
334: ptr[17]=(char)(hsgfmt>>24)&0xFF;
335: if (tno+1 > cdhitrack) {
336: frames=leadout;
337: }
338: else {
339: frames=((long)redbook[tno+1].minute*4500L)+((long)redbook[tno+1].second*75L)
340: +((long)redbook[tno+1].frame)-150L;
341: }
342: frames-=hsgfmt;
343: ptr[18]=(char)frames&0xFF;
344: ptr[19]=(char)(frames>>8)&0xFF;
345: ptr[20]=(char)(frames>>16)&0xFF;
346: ptr[21]=(char)(frames>>24)&0xFF;
347: memset(&rmregs,0,sizeof(struct rmregs));
348: rmregs.es=cmdseg;
349: rmregs.ebx=cmdoff;
350: rmregs.ecx=cddrive-'A';
351: rmregs.eax=0x1510;
352: rmint86(0x2F,&rmregs);
353: status=ptr[4];
354: if (status&0x01) {
355: return(1);
356: }
357: return(0);
358: }
359:
360: void
361: cd_resumeplay(void)
362: {
363: char far *ptr;
364:
365: ptr=LES_MKFP(cmdseg,cmdoff);
366: memset(ptr,0,CMDBUFSIZE);
367: ptr[0]=0x16;
368: ptr[1]=0x00;
369: ptr[2]=0x88;
370: memset(&rmregs,0,sizeof(struct rmregs));
371: rmregs.es=cmdseg;
372: rmregs.ebx=cmdoff;
373: rmregs.ecx=cddrive-'A';
374: rmregs.eax=0x1510;
375: rmint86(0x2F,&rmregs);
376: }
377:
378: #if 0
379: void
380: main(void)
381: {
382: short i;
383: unsigned short nameoff,nameseg;
384: char far *ptr;
385:
386: if ((cddrives=ismscdex())) {
387: if (alcmem(CMDBUFSIZE) == NULL) {
388: exit(0);
389: }
390: cmdseg=rmseg;
391: cmdoff=rmoff;
392: ptr=LES_MKFP(cmdseg,cmdoff);
393: printf("CD-ROM drive is %c\n",cddrive);
394: cd_getname();
395: nameseg=(unsigned short)(namebuf[4]<<8)+namebuf[3];
396: nameoff=(unsigned short)(namebuf[2]<<8)+namebuf[1];
397: cddevadr=LES_MKFP(nameseg,nameoff);
398: _fmemmove((char far *)&cddevname,cddevadr+10,8);
399: if ((cdhdl=open(cddevname,O_RDWR)) != -1) {
400: //cd_opendoor(cdhdl);
401: //printf("Insert CD then press a key\n");
402: //getch();
403: //cd_closedoor(cdhdl);
404: //printf("Door closed. Resetting drive\n");
405: cd_reset(cdhdl);
406: printf("Getting audio disk info\n");
407: cd_getaudiodisk(cdhdl);
408: printf("Getting and playing audio tracks\n");
409: for (i=cdlotrack ; i <= cdhitrack ; i++) {
410: cd_getaudiotrack(cdhdl,i);
411: }
412: for (i=cdlotrack ; i <= cdhitrack ; i++) {
413: if (cd_playtrack(i)) {
414: printf("Playing track %d...any key to stop\n",i);
415: getch();
416: }
417: }
418: cd_reset(cdhdl);
419: close(cdhdl);
420: }
421: }
422: }
423: #endif
424: #else // new code for CD-ROM detection - for Windows '95
425: #include "stdio.h"
426: #include "dos.h"
427: #include <memcheck.h>
428:
429: int cddrive;
430:
431: int
432: ismscdex(void)
433: {
434: union REGS regs;
435:
436: regs.x.eax=0x1500;
437: regs.x.ebx=0x0000;
438: int386(0x2F,®s,®s);
439: if (regs.x.ebx == 0) {
440: return(0);
441: }
442: cddrive='A'+regs.x.ecx;
443: return(cddrive);
444: }
445:
446: int
447: cd_init(void)
448: {
449: if (ismscdex()) {
450: return(1);
451: }
452: return(0);
453: }
454: #endif
455:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.