Аппаратное обеспечение персонального компьютера

       

Программа CDPLAY


Программа CDPLAY предназначена для проигрывания дорожек звуковых компакт-дисков. При запуске этой программы необходимо указать параметр – номер блока, с которого должно выполняться проигрывание.

Ниже мы привели пример запуска программы, передав ей адрес 512:

CDPLAY, (c) A. Frolov, 1997

Track Red book: 512

Track Sierra: 0

MSCDEX version: 2.95

Found 1 CD Unit, start unit: G

CD-ROM letters: G

Started. Press any key to stop and eject CD

Этот адрес мы взяли из листинга, полученного программой CDINFO, описанной в предыдущем разделе. Он был пересчитан программой CDPLAY в формат Sierra, в результате чего программа запустила проигрывание самой первой звуковой дорожки диска.

Если после запуска программы и начала проигрывания нажать любую клавишу, проигрывание будет остановлено, а компакт-диск - извлечен из устройства чтения CD-ROM.

Исходный текст программы CDPLAY приведен в листинге 9.2.

Листинг 9.2. Файл cdplay\cdplay.с



// =====================================================

// Проигрывание звуковых компакт-дисков

//

// (C) Фролов А.В, 1997

//

// E-mail: frolov@glas.apc.org

// WWW:    http://www.glasnet.ru/~frolov

//            или

//         http://www.dials.ccas.ru/frolov

// =====================================================

#include <stdio.h>

#include <stdlib.h>

#include <conio.h>

#include <dos.h>

#include <memory.h>

 

typedef unsigned char BYTE;

typedef unsigned int  WORD;

typedef unsigned long DWORD;

// Необходимо для обеспечения выравнивания

// полей структур на границу байта

#pragma pack(1)

// Заголовок запроса для обращения к драйверу

typedef struct _ReqHdr

{

  BYTE bSize;

  BYTE bSubUnit;

  BYTE bCmd;

  WORD wStatus;

  BYTE bReserved[8];   

} ReqHdr;

 

typedef struct _PlayAudio

{

  ReqHdr rh;

  BYTE bMode;

  DWORD dwLoc;

  DWORD dwSectorNum;

} PlayAudio;

// Запрос IOCTL Output

typedef struct _IOCTL_Output

{            

  ReqHdr rh;

  BYTE   bMediaDescriptor;


  DWORD  lpTransferAddress;

  WORD   wDataSize;

  WORD   wStartSector;

  DWORD  lpVolID;

} IOCTL_Output;      

// Запрос на извлечение компакт-диска

typedef struct _EjectDisk

{

  BYTE  bControl;

} EjectDisk;

#pragma pack()

// Прототипы функций

void GetCDLetters(BYTE *bLetters);

void CallCDDriver(void *rh, int nCDUnit);

int PlayAudioTrack( DWORD dwLoc, DWORD dwSectorNum, int nCDUnit);

int StopAudio(int nCDUnit);

int DeviceOpen(int nCDUnit);

int DeviceClose(int nCDUnit);

int EjectCD(int nCDUnit);

DWORD Red2Sierra(DWORD dwRedLoc);

// Регистры для вызова функции int86

union REGS rg;                     

// Количество установленных устройств чтения CD-ROM

int nCDUnits;

// Номер первого устройства чтения CD-ROM

int nCDStartUnit;

// Слово состояния после вызова драйвера CD-ROM

int iStatus;

                               

// Массив номеров установленных устройств CD-ROM

BYTE bLetters[26];

// ---------------------------------------------------

// main

// Точка входа в программу

// ---------------------------------------------------

int main(int argc, char *argv[])

{

  int i;

 

  DWORD dwStartTrack;

 

  printf("CDPLAY, (c) A. Frolov, 1997\n\n");

 

  dwStartTrack = 1;

  if(argc == 2)

  {

    dwStartTrack = atol(argv[1]);

    printf("Track Red book: %ld\n", dwStartTrack);

   

  }

  else

  {

    printf("Usage: CDPLAY <Red book sector address>\n");

    return -1;

  }

 

  // Преобразование адреса сектора в формат Sierra

  dwStartTrack = Red2Sierra(dwStartTrack);

  printf("Track Sierra: %ld\n", dwStartTrack);

 

  // Проверяем, установлена ли программа MSCDEX

  rg.x.ax = 0x1500;

  rg.x.bx = 0;

  int86(0x2f, &rg, &rg);

  if(rg.x.bx == 0)

  {

    printf("MSCDEX is not installed\n");

    return -1;

  }

 

  else       

  {

    // Сохраняем общее количество устройств чтения CD-ROM

    nCDUnits = rg.x.bx;



   

    // Сохраняем номер первого такого устройства

    nCDStartUnit = rg.x.cx;

    // Определяем и отображаем вресию MSCDEX

    rg.x.ax = 0x150c;

    int86(0x2f, &rg, &rg);

    printf("MSCDEX version: %d.%d\n", rg.h.bh, rg.h.bl);

    // Отображаем количество найденных устройств чтения

    // CD-ROM и номер первого устройства

    printf("Found % d CD Unit, start unit: %c\n",

      nCDUnits, nCDStartUnit + 'A');

  }

  // Получаем массив номеров устройств чтения CD-ROM

  GetCDLetters(bLetters);

 

  // Отображаем обозначения всех устройств CD-ROM

  printf("CD-ROM letters: ");

  for(i = 0; i < nCDUnits; i++)

  {

    printf("%c ", bLetters[i] + 'A'); 

  }

  printf("\n");

  // Открываем устройство

  iStatus = DeviceOpen(bLetters[0]);

  if(iStatus & 0x8000)

  {

    printf("DeviceOpen status: %04.4X\n", iStatus);

    return -1;

  }

  // Запускаем проигрывание

  iStatus =

    PlayAudioTrack(dwStartTrack, 0xffffffff, bLetters[0]);

  if(iStatus & 0x8000)

  {

    printf("PlayAudioTrack status: %04.4X\n", iStatus);

    return -1;

  }

  printf("Started. Press any key to stop and eject CD\n");

 

  // Ожидаем, пока пользователь не нажмет клавишу

  getch();

  // Останавливаем проигрывание

  iStatus = StopAudio(bLetters[0]);

  if(iStatus & 0x8000)

  {

    printf("StopAudio status: %04.4X\n", iStatus);

    return -1;

  }

  // Извлекаем диск

  iStatus = EjectCD(bLetters[0]);

  if(iStatus & 0x8000)

  {

    printf("EjectCD status: %04.4X\n", iStatus);

    return -1;

  }

  // Закрываем устройство

  iStatus = DeviceClose(bLetters[0]);

  if(iStatus & 0x8000)

  {

    printf("DeviceClose status: %04.4X\n", iStatus);

    return -1;

  }

  return 0;

}

// ---------------------------------------------------

// PlayAudioTrack



// Запуск проигрывания звукового компакт-диска

// ---------------------------------------------------

int PlayAudioTrack( DWORD dwLoc, DWORD dwSectorNum, int nCDUnit)

{

  PlayAudio cmd;

 

  memset(&cmd, 0, sizeof(PlayAudio));

 

  cmd.rh.bSize    = 22;

  cmd.rh.bSubUnit = 0;

  cmd.rh.bCmd     = 132;

 

  cmd.bMode  = 0;

  cmd.dwLoc  = dwLoc;

  cmd.dwSectorNum  = dwSectorNum;

 

  CallCDDriver(&cmd, nCDUnit);

  return cmd.rh.wStatus;



// ---------------------------------------------------

// StopAudio

// Остановка проигрывания звукового компакт-диска

// ---------------------------------------------------

int StopAudio(int nCDUnit)

{

  ReqHdr cmd;

 

  memset(&cmd, 0, sizeof(ReqHdr));

 

  cmd.bSize    = 13;

  cmd.bSubUnit = 0;

  cmd.bCmd     = 133;

 

  CallCDDriver(&cmd, nCDUnit);

  return (cmd.wStatus);



// ---------------------------------------------------

// DeviceOpen

// Открывание устройства

// ---------------------------------------------------

int DeviceOpen(int nCDUnit)

{

  ReqHdr cmd;

 

  memset(&cmd, 0, sizeof(ReqHdr));

 

  cmd.bSize    = 13;

  cmd.bSubUnit = 0;

  cmd.bCmd     = 13;

 

  CallCDDriver(&cmd, nCDUnit);

  return (cmd.wStatus);



// ---------------------------------------------------

// DeviceClose

// Закрывание устройства

// ---------------------------------------------------

int DeviceClose(int nCDUnit)

{

  ReqHdr cmd;

 

  memset(&cmd, 0, sizeof(ReqHdr));

 

  cmd.bSize    = 13;

  cmd.bSubUnit = 0;

  cmd.bCmd     = 14;

 

  CallCDDriver(&cmd, nCDUnit);

  return (cmd.wStatus);



// ---------------------------------------------------

// EjectCD

// Извлечение компакт-диска

// ---------------------------------------------------

int EjectCD(int nCDUnit)

{

  IOCTL_Output cmd;

  EjectDisk ed;

 

  memset(&cmd, 0, sizeof(IOCTL_Output));

 

  cmd.rh.bSize    = 14;

  cmd.rh.bSubUnit = 0;

  cmd.rh.bCmd     = 12;



 

  cmd.bMediaDescriptor  = 0;

  cmd.lpTransferAddress = (DWORD)(void far *)&ed;

  cmd.wDataSize         = 1;

  cmd.wStartSector      = 0;

  cmd.lpVolID           = (DWORD)(void far *)NULL;

 

  ed.bControl = 0;

 

  CallCDDriver(&cmd, nCDUnit);

  return cmd.rh.wStatus;



// ---------------------------------------------------

// CallCDDriver

// Вызов драйвера компакт-диска

// ---------------------------------------------------

void CallCDDriver(void *rh, int nCDUnit)

{

  static union REGS rg;

  static struct SREGS srg;

 

  segread(&srg);

  rg.x.ax = 0x1510;

  rg.x.cx = nCDUnit;

  rg.x.bx = FP_OFF(rh); 

 

  int86x(0x2f, &rg, &rg, &srg);

}

// ---------------------------------------------------

// GetCDLetters

// Заполнение массива номерами установленных

// в системе устройств чтения компакт-диска

// ---------------------------------------------------

void GetCDLetters(BYTE *bLetters)

{

  static union REGS rg;

  static struct SREGS srg;

 

  segread(&srg);

  rg.x.ax = 0x150d;

  rg.x.bx = FP_OFF(bLetters); 

 

  int86x(0x2f, &rg, &rg, &srg);

}

// ---------------------------------------------------

// Преобразование адреса дорожки из формата Red book

// в формат Sierra

// ---------------------------------------------------

DWORD Red2Sierra(DWORD dwRedLoc)

{

  BYTE bMin, bSec, bFrame;

  bMin   = (BYTE)((dwRedLoc >> 16) & 0xff);

  bSec   = (BYTE)((dwRedLoc >> 8) & 0xff);

  bFrame = (BYTE)(dwRedLoc & 0xff);

 

  return (DWORD)bMin * 75 * 60 + (DWORD)bSec * 75 +

    (DWORD)bFrame - 150;

}


Содержание раздела