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