⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cdrom.c

📁 控制cdrom播放音乐的程序。
💻 C
📖 第 1 页 / 共 2 页
字号:
/*                          CDROM AUDIO ROUTINES
			      By Barry Egerter

			    Written July 18, 1994

			    Using Borland C++ 3.1

		   Code : FREEWARE - alter and use at will.


		Internet Email:      barry.egerter@softnet.com
*/
#include <dos.h>
#include <io.h>
#include <mem.h>
#include <fcntl.h>

#define CDROM 0x21
#define EJECT_TRAY 0
#define RESET 2
#define CLOSE_TRAY 5
#define MEDIA_CHANGE 9
#define BUSY  512
#define TRACK_MASK 208

typedef struct playinfo {
  unsigned char control;
  unsigned char adr;
  unsigned char track;
  unsigned char index;
  unsigned char min;
  unsigned char sec;
  unsigned char frame;
  unsigned char zero;
  unsigned char amin;
  unsigned char asec;
  unsigned char aframe;
};


typedef struct volumeinfo {
    unsigned char mode;
    unsigned char input0;
    unsigned char volume0;
    unsigned char input1;
    unsigned char volume1;
    unsigned char input2;
    unsigned char volume2;
    unsigned char input3;
    unsigned char volume3;
};


struct {
  unsigned short drives;
  unsigned char  first_drive;
  unsigned short current_track;
  unsigned long  track_position;
  unsigned char  track_type;
  unsigned char  low_audio;
  unsigned char  high_audio;
  unsigned char  disk_length_min;
  unsigned char  disk_length_sec;
  unsigned char  disk_length_frames;
  unsigned long	 endofdisk;
  unsigned char  upc[7];
  unsigned char  diskid[6];
  unsigned long  status;
  unsigned short error;      /* See description below */
} cdrom_data;

/* CDROM_DATA.ERROR Description

  Bit 15         - Error bit
  Bit 14-10      - Reserved
  Bit  9         - Busy
  Bit  8         - Done
  Bit  7-0       - Error code (bit 15 on)

Error codes are the following:

  0  Write-protect violation
  1  Unknown unit
  2  Drive not ready
  3  Unknown command
  4  CRC error
  5  Bad drive request structure length
  6  Seek error
  7  Unknown media
  8  Sector not found
  9  Printer out of paper
  A  Write fault
  B  Read fault
  C  General failure
  D  Reserved
  E  Reserved
  F  Invalid disk change
*/


/*   Multiplex Interrupt routines
     "borrowed" from Ralf Brown's MSDOS Interrupt List v4.1

INT 21 - CD-ROM device driver - IOCTL INPUT
	AX = 4402h
	BX = file handle referencing character device for CD-ROM driver
	CX = number of bytes to read
	DS:DX -> control block (see #0563)
Return: CF clear if successful
	    AX = number of bytes actually read
	CF set on error
	    AX = error code (01h,05h,06h,0Dh) (see #0770 at AH=59h)
Note:	the data returned depends on the first byte of the control block; the
	  remainder of the control block is filled by the driver
SeeAlso: AX=4403h"CD-ROM",INT 2F/AX=0802h

(Table 0562)
Values for CD-ROM data being requested:
 00h	device driver header address
 01h	drive head location
 02h	reserved
 03h	error statistics
 04h	audio channel info
 05h	raw drive bytes (uninterpreted and device-specific)
 06h	device status
 07h	sector size
 08h	volume size
 09h	media change status
 0Ah	audio disk info
 0Bh	audio track info
 0Ch	audio Q-Channel info
 0Dh	audio sub-channel info
 0Eh	UPC code

Format of CD-ROM control block:
Offset	Size	Description	(Table 0563)
 00h	BYTE	data being requested (see #0562)
---function 00h---
 01h	DWORD	device driver header address (see also AH=52h)
---function 01h---
 01h	BYTE	addressing mode
		00h HSG
		01h Red Book
 02h	DWORD	current location of drive's head
		logical sector number in HSG mode
		frame/second/minute/unused in Red Book mode
		(HSG sector = minute * 4500 + second * 75 + frame - 150)
---function 03h---
 01h  N BYTEs	undefined as of 5 Aug 88 specification
---function 04h---
 01h	BYTE	input channel (0-3) for output channel 0
 02h	BYTE	volume for output channel 0
 03h	BYTE	input channel (0-3) for output channel 1
 04h	BYTE	volume for output channel 1
 05h	BYTE	input channel (0-3) for output channel 2
 06h	BYTE	volume for output channel 2
 07h	BYTE	input channel (0-3) for output channel 3
 08h	BYTE	volume for output channel 3
Notes:	output channels 0 and 1 are left and right, 2 and 3 are left prime and
	  right prime; a volume of 00h is off
	the default setting is for each input channel to be assigned to the
	  same-numbered output channel at full (FFh) volume
---function 05h---
 01h	BYTE	number of bytes read
 02h 128 BYTEs	buffer for drive bytes
---function 06h---
 01h	DWORD	device parameters (see #0564)
---function 07h---
 01h	BYTE	read mode
		00h cooked
		01h raw
 02h	WORD	sector size in bytes
---function 08h---
 01h	DWORD	volume size in sectors
---function 09h---
 01h	BYTE	media change status
		00h don't know
		01h media unchanged
		FFh media has been changed
---function 0Ah---
 01h	BYTE	lowest audio track number
 02h	BYTE	highest audio track number
 03h	DWORD	start address of lead-out track (Red Book format)
--function 0Bh---
 01h	BYTE	track number (set by caller)
 02h	DWORD	starting point of track (Red Book format)
 06h	BYTE	track control info
		bits 15,14,12: track type (notice: bits not contiguous!)
			000 two audio channels, no pre-emphasis
			001 two audio channels with pre-emphasis
			010 data track
			100 four audio channels, no pre-emphasis
			101 four audio channels with pre-emphasis
			other reserved
		bit 13: digital copy permitted
---function 0Ch---
 01h	BYTE	CONTROL and ADR byte (as received from drive)
 02h	BYTE	track number
 03h	BYTE	point or index
 04h	BYTE	minute	\
 05h	BYTE	second	 > running time within track
 06h	BYTE	frame	/
 07h	BYTE	zero
 08h	BYTE	"AMIN" or "PMIN"     \
 09h	BYTE	"ASEC" or "PSEC"      > running time on disk
 0Ah	BYTE	"AFRAME" or "PFRAME" /
---function 0Dh---
 01h	DWORD	starting frame address (Red Book format)
 05h	DWORD	transfer address
 09h	DWORD	number of sectors to read
Note:	copies 96 bytes of sub-channel info per sector into buffer
---function 0Eh---
 01h	BYTE	CONTROL and ADR byte
 02h  7 BYTEs	UPC/EAN code (13 BCD digits,low-order nybble of last byte is 0)
 09h	BYTE	zero
 0Ah	BYTE	"AFRAME"

Bitfields for CD-ROM device parameters:
Bit(s)	Description	(Table 0564)
 0	door open
 1	door unlocked
 2	supports raw reading in addition to cooked
 3	writable
 4	can play audio/video tracks
 5	supports interleaving
 6	reserved
 7	supports prefetch requests
 8	supports audio channel control
 9	supports Red Book addressing in addition to HSG
 10	audio is playing
*/

static union REGS inregs, outregs;
static struct SREGS sregs;


void device_request (void *block)
{
  inregs.x.ax = 0x1510;
  inregs.x.cx = cdrom_data.first_drive;
  inregs.x.bx = FP_OFF (block);
  sregs.es = FP_SEG (block);
  int86x (0x2f, &inregs, &outregs, &sregs);
}


void red_book (unsigned long value, unsigned char *min, unsigned char *sec, unsigned char *frame)
{
  *frame = value & 0x000000ff;
  *sec = (value & 0x0000ff00) >> 8;
  *min = (value & 0x00ff0000) >> 16;
}


unsigned long hsg (unsigned long value)
{
  unsigned char min, sec, frame;

  red_book (value, &min, &sec, &frame);
  value = (unsigned long)min * 4500;
  value += (short)sec * 75;
  value += frame - 150;
  return value;
}


unsigned long cd_head_position (void)
{
  struct {
    unsigned char length;
    unsigned char subunit;
    unsigned char comcode;
    unsigned short status;
    char ununsed[8];
    unsigned char media;
    unsigned long address;
    unsigned short bytes;
    unsigned short sector;
    unsigned long  volid;
    unsigned char unused[4];
  } tray_request;

  struct {
    unsigned char mode;
    unsigned char adr_mode;
    unsigned long address;
  } head_data;

  tray_request.length = sizeof (tray_request);
  tray_request.subunit = 0;
  tray_request.comcode = 3;
  tray_request.media = tray_request.sector = tray_request.volid = 0;
  tray_request.address = (unsigned long)&head_data;
  tray_request.bytes = 6;
  head_data.mode = 0x01;
  head_data.adr_mode = 0x00;
  device_request (&tray_request);
  cdrom_data.error = tray_request.status;
  return head_data.address;
}


void cd_get_volume (struct volumeinfo *vol)
{
  struct {
    unsigned char length;
    unsigned char subunit;
    unsigned char comcode;
    unsigned short status;
    char ununsed[8];
    unsigned char media;
    unsigned long address;
    unsigned short bytes;
    unsigned short sector;
    unsigned long  volid;
  } tray_request;

  tray_request.length = sizeof (tray_request);
  tray_request.subunit = 0;
  tray_request.comcode = 3;
  tray_request.media = 0;
  tray_request.media = tray_request.sector = tray_request.volid = 0;
  tray_request.address = (unsigned long)vol;
  tray_request.bytes = 9;
  vol->mode = 0x04;
  device_request (&tray_request);
  cdrom_data.error = tray_request.status;
}


void cd_set_volume (struct volumeinfo *vol)
{
  struct {
    unsigned char length;
    unsigned char subunit;
    unsigned char comcode;
    unsigned short status;
    char ununsed[8];
    unsigned char media;
    unsigned long address;
    unsigned short bytes;
    unsigned char unused[4];
  } cd_request;

  vol->mode = 3;
  cd_request.length = sizeof (cd_request);
  cd_request.subunit = 0;
  cd_request.comcode = 12;
  cd_request.media = 0;
  cd_request.address = (unsigned long)vol;
  cd_request.bytes = 9;
  device_request (&cd_request);
  cdrom_data.error = cd_request.status;
}


short cd_getupc (void)
{
  struct {
    unsigned char length;
    unsigned char subunit;
    unsigned char comcode;
    unsigned short status;
    char ununsed[8];
    unsigned char media;
    unsigned long address;
    unsigned short bytes;
    unsigned short sector;
    unsigned long  volid;
  } tray_request;

  struct {
    unsigned char mode;
    unsigned char adr;
    unsigned char upc[7];
    unsigned char zero;
    unsigned char aframe;
  } upc_data;
  tray_request.length = sizeof (tray_request);
  tray_request.subunit = 0;
  tray_request.comcode = 3;
  tray_request.media = 0;
  tray_request.media = tray_request.sector = tray_request.volid = 0;
  tray_request.address = (unsigned long)&upc_data;
  tray_request.bytes = 11;
  upc_data.mode = 0x0e;
  upc_data.adr = 2;
  device_request (&tray_request);
  cdrom_data.error = tray_request.status;
  if (upc_data.adr == 0)
    memset (&upc_data.upc, 0, 7);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -