/*  CDVol controls output volume of CD player */

#include <stdio.h>
#include <stdlib.h>
#include <dos.h>
#include <string.h>
#include <alloc.h>

#define MULTIPLEX_INT   0x2f
#define INIT_MP_INT     0x1500
#define CDREQ_MP_INT    0x1510

#define STAT_HAS_AN_ERROR 0x8000
#define STAT_BUSY         0x0200
#define STAT_DONE         0x0100

int CDRomLoaded,CDRomDrive;

#define WRITE_IOCTL_COMMAND  12
#define AUDIO_CHANNEL_CTRL   3

typedef struct {
  unsigned char ParamLength;
  unsigned char SubUnit;
  unsigned char CommandCode;
  unsigned int  Status;
  unsigned long Reserved1;
  unsigned long Reserved2;

  unsigned char Meddescr;
  unsigned long Transfaddr;
  unsigned int  Numbytes;
  unsigned int  Startsec;
  unsigned long volID;
} IOCTLStruc;


typedef struct {
       unsigned char CntrlCode;
       unsigned char InputChan0;
       unsigned char VolChan0;
       unsigned char InputChan1;
       unsigned char VolChan1;
       unsigned char InputChan2;
       unsigned char VolChan2;
       unsigned char InputChan3;
       unsigned char VolChan3;
} AudCtrlStruc;


AudCtrlStruc AudCtrlBlock;
IOCTLStruc IOCTLBlock;

int CDRomLoaded,CDRomDrive;


main(int argc, char *argv[])
{
       if (!CheckCD2F()){
               printf("MSCDEX NOT LOADED\n");
               exit(1);
       }

       if(argc > 2)
          SetVol( (unsigned char)atoi(argv[1]),(unsigned char)atoi(argv[2]) );
       else
       {
               printf("CDVOL Sets audio output volume of CD-ROM\n");
               printf("usage: cdvol <leftvol 0-255> <rightvol 0-255>\n");
       }
}

CheckCD2F()
{
union REGS regs;

       regs.x.ax = INIT_MP_INT;
       int86(MULTIPLEX_INT,&regs,&regs);
       CDRomLoaded = regs.x.bx;
       CDRomDrive = regs.x.cx;
}

SetVol(unsigned char Leftvol, unsigned char Rightvol)
{
union REGS regs;
struct SREGS sregs;

       AudCtrlBlock.CntrlCode = AUDIO_CHANNEL_CTRL;

       AudCtrlBlock.InputChan0 = 0;
       AudCtrlBlock.VolChan0 = Leftvol;
       AudCtrlBlock.InputChan1 = 1;
       AudCtrlBlock.VolChan1 = Rightvol;
       AudCtrlBlock.InputChan2 = 2;
       AudCtrlBlock.VolChan2 = 0;
       AudCtrlBlock.InputChan3 = 3;
       AudCtrlBlock.VolChan3 = 0;

       IOCTLBlock.ParamLength = 13;
       IOCTLBlock.SubUnit     = 0;
       IOCTLBlock.CommandCode = WRITE_IOCTL_COMMAND;
       IOCTLBlock.Status      = 0;

       IOCTLBlock.Meddescr = 0;
       IOCTLBlock.Transfaddr =  (unsigned long)&AudCtrlBlock;
       IOCTLBlock.Numbytes = 9;
       IOCTLBlock.Startsec = 0;
       IOCTLBlock.volID = 0;

       regs.x.ax = CDREQ_MP_INT;
       regs.x.bx = FP_OFF(&IOCTLBlock);
       regs.x.cx = CDRomDrive;
       sregs.es  = FP_SEG(&IOCTLBlock);

       int86x(MULTIPLEX_INT,&regs,&regs,&sregs);

       return(IOCTLBlock.Status);
}