home *** CD-ROM | disk | FTP | other *** search
/ Collection of Hack-Phreak Scene Programs / cleanhpvac.zip / cleanhpvac / FAQSYS18.ZIP / FAQS.DAT / CDROMFAQ.100 < prev    next >
Internet Message Format  |  1995-12-12  |  25KB

  1. From marcj@nando.net Wed Mar  1 17:51:03 1995
  2. From: marcj@nando.net (MarcJ)
  3. Newsgroups: comp.os.msdos.programmer
  4. Subject: CD-ROM FAQ
  5. Date: 19 Feb 1995 23:18:50 -0500
  6. Organization: NandO -- The News & Observer online service
  7. NNTP-Posting-Host: parsifal.nando.net
  8.  
  9. In recognition of a number of questions I've seen recently asking 
  10. questions on programming CD-ROMs...
  11.  
  12. CD-ROM programming FAQ Version 1.00
  13.  
  14. Copyright (C) 1995 by Marcus W. Johnson. All rights reserved. This
  15. article is not in the public domain, but it may be redistributed so
  16. long as this notice, the acknowledgments, and the information on
  17. obtaining the latest copy of this list are retained and no fee is
  18. charged. The code fragments may be used freely; credit would be
  19. polite.
  20.  
  21. ------- Table of Contents --------------------------------------------
  22.  
  23. Section 0 - Availability
  24.  0.01. How can I get the latest copy of this FAQ?
  25. Section 1 - MSCDEX Status
  26.  1.01. How do I know if MSCDEX is installed?
  27.  1.02. How do I determine the MSCDEX version?
  28. Section 2 - CD-ROM Existence
  29.  2.01. How many CD-ROMs are present?
  30.  2.02. Which drives are CD-ROMs?
  31.  2.03. How do I get the name of the CD-ROM device driver?
  32. Section 3 - Drive Interface
  33.  3.01. How do I open the door?
  34.  3.02. How do I close the door?
  35.  3.03. How do I unlock the door?
  36.  3.04. How do I lock the door?
  37.  3.05. How do I reset the drive?
  38.  3.06. How do I get drive status?
  39. Section 4 - Drive Capacity
  40.  4.01. What sector size is supported?
  41.  4.02. How many sectors are on the disk?
  42.  4.03. How much data is on the disk?
  43. Section 5 - Volume Table of Contents
  44.  5.01. How do I get the abstract file name?
  45.  5.02. How do I get the bibliography file name?
  46.  5.03. How do I get the copyright file name?
  47.  5.04. How do I read the Volume Table of Contents (VTOC)?
  48. Section 6 - Audio
  49.  6.01. How do I find out how many tracks are on a CD?
  50.  6.02. What are Red Book and HSG formats?
  51.  6.03. How can I determine where a particular track starts?
  52.  6.04. How do I play audio?
  53.  6.05. How do I pause audio playback?
  54.  6.06. How do I resume audio playback?
  55.  
  56. ======================================================================
  57. Section 0 - Administration
  58. ----------------------------------------------------------------------
  59. 0.01. How can I get the latest copy of this FAQ?
  60.  
  61.       The FAQ is published monthly in comp.os.msdos.programming and
  62.       alt.msdos.programmer.
  63. ----------------------------------------------------------------------
  64. 0.02. Where did this information come from?
  65.  
  66.       Ralf Brown's interrupt list
  67.       "MS-DOS Extensions", by Ray Duncan, Microsoft Press
  68.       My personal research for "PC-Programmer's Guide to Low-Level
  69.       Functions and Interrupts", Sams
  70.       The mention of particular books or programs must not be construed
  71.       to reflect unfavorably on any that are not mentioned.
  72. ----------------------------------------------------------------------
  73. 0.03. How accurate is this information?
  74.  
  75.       I have personally tested the code fragments in this FAQ, and
  76.       they appear to work as advertised, but there is no warranty on
  77.       the code or on the techniques described in this article.
  78.       As testing may not have been perfect, and machines and
  79.       configurations vary, it is possible that the fragments will not
  80.       work for you.
  81.       Please send corrections to marcj@nando.net.
  82. ======================================================================
  83. Section 1 - MSCDEX Status
  84. ======================================================================
  85. 1.01. How do I know if MSCDEX is installed?
  86.  
  87.       Call the MSCDEX installation check function. Here's code that
  88.       performs the check:
  89.  
  90.       mov  AX,0DADAH
  91.       push AX
  92.       mov  AX,01100H
  93.       int  2FH
  94.       pop  BX
  95.       cmp  BX,0ADADH
  96.       jne  not_installed
  97.       cmp  AL,0FFH
  98.       jne  not_installed
  99.       ;
  100.       ; MSCDEX is installed
  101.       ;
  102. ----------------------------------------------------------------------
  103. 1.02. How do I determine the MSCDEX version?
  104.  
  105.       Call the MSCDEX version check function. Here's code that gets
  106.       the version:
  107.  
  108.       mov  AX,150CH
  109.       int  2FH
  110.       ;
  111.       ; BH holds the major version
  112.       ; BL holds the minor version
  113.       ; Prior to MSCDEX version 2.0, the version returned is 0.0 (BX =
  114.       ; 0)
  115.       ;
  116. ======================================================================
  117. Section 2 - CD-ROM Existence
  118. ======================================================================
  119. 2.01. How many CD-ROMs are present?
  120.  
  121.       Ask MSCDEX. Here's code that gives the count of CD-ROMs
  122.       installed and the drive letter of the first one:
  123.  
  124.       mov  AX,1500H
  125.       xor  BX,BX
  126.       int  2FH
  127.       ;
  128.       ; BX will hold the number of CD-ROMs
  129.       ; CL will hold the first CD-ROM's drive; 0 = A:, 1 = B:, and so
  130.       ; on
  131.       ;
  132.  
  133.       A problem with this method, BTW, is that it conflicts with DOS
  134.       4.0's GRAPHICS.COM.
  135. ----------------------------------------------------------------------
  136. 2.02. Which drives are CD-ROMs?
  137.  
  138.       There are two ways to find out. Both ways require MSCDEX version
  139.       2 (see question 1.02, How do I determine the MSCDEX version?).
  140.       The first way gives a list of all CD-ROM drives; the second
  141.       verifies whether a specific drive is a CD-ROM.
  142.  
  143.       Method 1: (get list of CD-ROMs)
  144.       This method requires a block of memory; the size, in bytes, must
  145.       be at least the number of drives returned by function 1500H (see
  146.       question 2.01, How many CD-ROMs are present?).
  147.  
  148.       mov  AX,150DH
  149.       les  BX,LetterArray
  150.       int    2FH
  151.       ;
  152.       ; each byte in LetterArray will contain a drive value (0 = A:, 1
  153.       ; = B:, etc.)
  154.       ;
  155.  
  156.       Method 2: (is a specified drive a CD-ROM?)
  157.  
  158.       mov  AX,150BH
  159.       mov  CX,Drive  ; 0 = A:, 1 = B:, and so on
  160.       int  2FH
  161.       or   AX,AX
  162.       jz   not_cd_rom
  163.       cmp  BX,0ADADH
  164.       jne  not_cd_rom
  165.       ;
  166.       ; the drive is a CD-ROM
  167.       ;
  168. ----------------------------------------------------------------------
  169. 2.03. How do I get the name of the CD-ROM device driver?
  170.  
  171.       First, you need to know how many CD-ROMs you have (see question
  172.       2.01, How many CD-ROMs are present?). You need a block of memory
  173.       whose size, in bytes, is 5 times the number of CD-ROMs present.
  174.       This code will fill that array:
  175.  
  176.       mov  AX,1501H
  177.       les  BX,DriverArray
  178.       int  2FH
  179.  
  180.       Each 5-byte element in the array consists of the drive's subunit
  181.       number (a CD-ROM device driver may support several drives as
  182.       subunits), followed by the address of the drive's device driver.
  183.       The filename is 10 bytes into the device driver. The filename is
  184.       at most 8 bytes long, and if less than 8 bytes, is terminated by
  185.       a space (20H).
  186. ======================================================================
  187. Section 3 - Drive Interface
  188. ======================================================================
  189. 3.01. How do I open the door?
  190.  
  191.       First, you need the name of the device driver (see question 2.03,
  192.       How do I get the name of the CD-ROM device driver?). Open the
  193.       file for read/write and obtain the file handle (DOS function 3DH
  194.       will suffice).
  195.  
  196.       Once you have the file handle, you need a one byte block of
  197.       memory. Call DOS IOCTL function 4403H, as shown here:
  198.  
  199.       mov  BX,FileHandle
  200.       mov  Command,0
  201.       lds  DX,Command
  202.       mov  CX,1
  203.       mov  AX,4403H
  204.       int  21H
  205.       jc   error
  206.       cmp  AX,1
  207.       jne  write_error
  208.       ;
  209.       ; door should be open
  210.       ;
  211.  
  212.       On error (carry set), AX will hold an error code: 0001H (invalid
  213.       function), 0005H (access denied), 0006H (invalid handle), or
  214.       000DH (invalid data).
  215. ----------------------------------------------------------------------
  216. 3.02. How do I close the door?
  217.  
  218.       First, you need the name of the device driver (see question 2.03,
  219.       How do I get the name of the CD-ROM device driver?). Open the
  220.       file for read/write and obtain the file handle (DOS function 3DH
  221.       will suffice).
  222.  
  223.       Once you have the file handle, you need a one byte block of
  224.       memory. Call DOS IOCTL function 4403H, as shown here:
  225.  
  226.       mov  BX,FileHandle
  227.       mov  Command,5
  228.       lds  DX,Command
  229.       mov  CX,1
  230.       mov  AX,4403H
  231.       int  21H
  232.       jc   error
  233.       cmp  AX,1
  234.       jne  write_error
  235.       ;
  236.       ; door should be closed
  237.       ;
  238.  
  239.       On error (carry set), AX will hold an error code: 0001H (invalid
  240.       function), 0005H (access denied), 0006H (invalid handle), or
  241.       000DH (invalid data).
  242.  
  243.       The drive should be reset after closing the door before
  244.       accessing the drive (see question 3.05, How do I reset the
  245.       drive?).
  246. ----------------------------------------------------------------------
  247. 3.03. How do I unlock the door?
  248.  
  249.       First, you need the name of the device driver (see question 2.03,
  250.       How do I get the name of the CD-ROM device driver?). Open the
  251.       file for read/write and obtain the file handle (DOS function 3DH
  252.       will suffice).
  253.  
  254.       Once you have the file handle, you need a two-byte block of
  255.       memory. Call DOS IOCTL function 4403H, as shown here:
  256.  
  257.       mov  BX,FileHandle
  258.       mov  Command,1
  259.       mov  Command+1,0
  260.       lds  DX,Command
  261.       mov  CX,2
  262.       mov  AX,4403H
  263.       int  21H
  264.       jc   error
  265.       cmp  AX,2
  266.       jne  write_error
  267.       ;
  268.       ; door should be unlocked
  269.       ;
  270.  
  271.       On error (carry set), AX will hold an error code: 0001H (invalid
  272.       function), 0005H (access denied), 0006H (invalid handle), or
  273.       000DH (invalid data).
  274.  
  275.       The drive should be reset after unlocking the door before
  276.       accessing the drive (see question 3.05, How do I reset the
  277.       drive?).
  278. ----------------------------------------------------------------------
  279. 3.04. How do I lock the door?
  280.  
  281.       First, you need the name of the device driver (see question 2.03,
  282.       How do I get the name of the CD-ROM device driver?). Open the
  283.       file for read/write and obtain the file handle (DOS function 3DH
  284.       will suffice).
  285.  
  286.       Once you have the file handle, you need a two-byte block of
  287.       memory. Call DOS IOCTL function 4403H, as shown here:
  288.  
  289.       mov  BX,FileHandle
  290.       mov  Command,1
  291.       mov  Command+1,1
  292.       lds  DX,Command
  293.       mov  CX,2
  294.       mov  AX,4403H
  295.       int  21H
  296.       jc   error
  297.       cmp  AX,2
  298.       jne  write_error
  299.       ;
  300.       ; door should be locked
  301.       ;
  302.  
  303.       On error (carry set), AX will hold an error code: 0001H (invalid
  304.       function), 0005H (access denied), 0006H (invalid handle), or
  305.       000DH (invalid data).
  306.  
  307.       The drive should be reset after locking the door before
  308.       accessing the drive (see question 3.05, How do I reset the
  309.       drive?).
  310. ----------------------------------------------------------------------
  311. 3.05. How do I reset the drive?
  312.  
  313.       First, you need the name of the device driver (see question 2.03,
  314.       How do I get the name of the CD-ROM device driver?). Open the
  315.       file for read/write and obtain the file handle (DOS function 3DH
  316.       will suffice).
  317.  
  318.       Once you have the file handle, you need a one-byte block of
  319.       memory. Call DOS IOCTL function 4403H, as shown here:
  320.  
  321.       mov  BX,FileHandle
  322.       mov  Command,2
  323.       lds  DX,Command
  324.       mov  CX,1
  325.       mov  AX,4403H
  326.       int  21H
  327.       jc   error
  328.       cmp  AX,1
  329.       jne  write_error
  330.       ;
  331.       ; drive should be reset
  332.       ;
  333.  
  334.       On error (carry set), AX will hold an error code: 0001H (invalid
  335.       function), 0005H (access denied), 0006H (invalid handle), or
  336.       000DH (invalid data).
  337. ----------------------------------------------------------------------
  338. 3.06. How do I get drive status?
  339.  
  340.       First, you need the name of the device driver (see question 2.03,
  341.       How do I get the name of the CD-ROM device driver?). Open the
  342.       file for read/write and obtain the file handle (DOS function 3DH
  343.       will suffice).
  344.  
  345.       Once you have the file handle, you need a five-byte block of
  346.       memory. Call DOS IOCTL function 4402H, as shown here:
  347.  
  348.       mov  BX,FileHandle
  349.       mov  Command,6
  350.       lds  DX,Command
  351.       mov  CX,5
  352.       mov  AX,4402H
  353.       int  21H
  354.       jc   error
  355.       cmp  AX,5
  356.       jne  read_error
  357.       ;
  358.       ; The word at offset 1 of the five-byte block of memory contains
  359.       ; status
  360.       ; bit 10 is set if audio is playing
  361.       ; bit  9 is set if Red Book and HSG addressing are both
  362.       ;                  supported
  363.       ; bit  8 is set if audio channel control is supported
  364.       ; bit  7 is set if prefetch requests are supported
  365.       ; bit  5 is set if interleaving is supported
  366.       ; bit  4 is set if audio/video track playback is supported
  367.       ; bit  3 is set if the CD-ROM is writable
  368.       ; bit  2 is set if raw and cooked read is supported
  369.       ; bit  1 is set if the door is unlocked
  370.       ; bit  0 is set if the door is open
  371.       ;
  372.  
  373.       On error (carry set), AX will hold an error code: 0001H (invalid
  374.       function), 0005H (access denied), 0006H (invalid handle), or
  375.       000DH (invalid data).
  376.  
  377.       The drive should be reset after checking drive status before
  378.       accessing the drive (see question 3.05, How do I reset the
  379.       drive?).
  380. ======================================================================
  381. Section 4 - Drive Capacity
  382. ======================================================================
  383. 4.01. What sector size is supported?
  384.  
  385.       First, you need the name of the device driver (see question 2.03,
  386.       How do I get the name of the CD-ROM device driver?). Open the
  387.       file for read/write and obtain the file handle (DOS function 3DH
  388.       will suffice).
  389.  
  390.       Once you have the file handle, you need a four-byte block of
  391.       memory. Call DOS IOCTL function 4402H, as shown here:
  392.  
  393.       mov  BX,FileHandle
  394.       mov  Command,7
  395.       lds  DX,Command
  396.       mov  CX,4
  397.       mov  AX,4402H
  398.       int  21H
  399.       jc   error
  400.       cmp  AX,4
  401.       jne  read_error
  402.       ;
  403.       ; The byte at offset 1 of the four-byte block of memory contains
  404.       ; raw/cooked status (0 = cooked, 1 = raw)
  405.       ; The word at offset 2 of the four-byte block of memory contains
  406.       ; the sector size
  407.  
  408.       On error (carry set), AX will hold an error code: 0001H (invalid
  409.       function), 0005H (access denied), 0006H (invalid handle), or
  410.       000DH (invalid data).
  411.  
  412.       The drive should be reset after getting the sector size before
  413.       accessing the drive (see question 3.05, How do I reset the
  414.       drive?).
  415. ----------------------------------------------------------------------
  416. 4.02. How many sectors are on the disk?
  417.  
  418.       First, you need the name of the device driver (see question 2.03,
  419.       How do I get the name of the CD-ROM device driver?). Open the
  420.       file for read/write and obtain the file handle (DOS function 3DH
  421.       will suffice).
  422.  
  423.       Once you have the file handle, you need a five-byte block of
  424.       memory. Call DOS IOCTL function 4402H, as shown here:
  425.  
  426.       mov  BX,FileHandle
  427.       mov  Command,8
  428.       lds  DX,Command
  429.       mov  CX,5
  430.       mov  AX,4402H
  431.       int  21H
  432.       jc   error
  433.       cmp  AX,5
  434.       jne  read_error
  435.       ;
  436.       ; The dword at offset 1 of the five-byte block of memory
  437.       ; contains the number of sectors
  438.  
  439.       On error (carry set), AX will hold an error code: 0001H (invalid
  440.       function), 0005H (access denied), 0006H (invalid handle), or
  441.       000DH (invalid data).
  442.  
  443.       The drive should be reset after getting the number of sectors
  444.       before accessing the drive (see question 3.05, How do I reset
  445.       the drive?).
  446. ----------------------------------------------------------------------
  447. 4.03. How much data is on the disk?
  448.  
  449.       See question 4.01, What sector size is supported?, and question
  450.       4.02, How many sectors are on the disk?. Take the product of the
  451.       two values returned. The conventional DOS functions don't work
  452.       reliably.
  453. ======================================================================
  454. Section 5 - Volume Table of Contents
  455. ======================================================================
  456. 5.01. How do I get the abstract file name?
  457.  
  458.       You need a 38-byte block of memory to hold the abstract file
  459.       name. This code will fill that block:
  460.  
  461.       les  BX,Buffer
  462.       mov  CX,Drive    ; must be in format 0 = A:, 1 = B:, etc.
  463.       mov  AX,1503H
  464.       int  2FH
  465.       jc   error
  466.       ;
  467.       ; buffer is filled with the abstract file name.
  468.       ;
  469.  
  470.       The file name is nul-terminated.
  471.  
  472.       The drive should be reset after getting the abstract file name
  473.       before accessing the drive (see question 3.05, How do I reset
  474.       the drive?).
  475. ----------------------------------------------------------------------
  476. 5.02. How do I get the bibliography file name?
  477.  
  478.       You need a 38-byte block of memory to hold the bibliography file
  479.       name. This code will fill that block:
  480.  
  481.       les  BX,Buffer
  482.       mov  CX,Drive    ; must be in format 0 = A:, 1 = B:, etc.
  483.       mov  AX,1504H
  484.       int  2FH
  485.       jc   error
  486.       ;
  487.       ; buffer is filled with the bibliography file name.
  488.       ;
  489.  
  490.       The file name is nul-terminated.
  491.  
  492.       The drive should be reset after getting the bibliography file
  493.       name before accessing the drive (see question 3.05, How do I
  494.       reset the drive?).
  495. ----------------------------------------------------------------------
  496. 5.03. How do I get the copyright file name?
  497.  
  498.       You need a 38-byte block of memory to hold the copyright file
  499.       name. This code will fill that block:
  500.  
  501.       les  BX,Buffer
  502.       mov  CX,Drive    ; must be in format 0 = A:, 1 = B:, etc.
  503.       mov  AX,1502H
  504.       int  2FH
  505.       jc   error
  506.       ;
  507.       ; buffer is filled with the copyright file name.
  508.       ;
  509.  
  510.       The file name is nul-terminated.
  511.  
  512.       The drive should be reset after getting the copyright file name
  513.       before accessing the drive (see question 3.05, How do I reset
  514.       the drive?).
  515. ----------------------------------------------------------------------
  516. 5.04. How do I read the Volume Table of Contents (VTOC)?
  517.  
  518.       The VTOC is read in 2048-byte blocks. This code fills a VTOC
  519.       block:
  520.  
  521.       les  BX,Buffer
  522.       mov  CX,Drive       ; must be in format 0 = A:, 1 = B:, etc.
  523.       mov  DX,BlockNumber ; 0 for the first block
  524.       mov  AX,1505H
  525.       int  2FH
  526.       jc   error
  527.       ;
  528.       ; block is filled
  529.       ;
  530.       ; AX contains the descriptor type for this block:
  531.       ;  0001H = standard volume descriptor
  532.       ;  00FFH = volume descriptor terminator
  533.       ;
  534.  
  535.       On error, AX will hold an error value: 000FH (invalid drive) or
  536.       0015H (drive not ready).
  537. ======================================================================
  538. Section 6 - Audio
  539. ======================================================================
  540. 6.01. How do I find out how many tracks are on a CD?
  541.  
  542.       First, you need the name of the device driver (see question
  543.       2.03, How do I get the name of the CD-ROM device driver?). Open
  544.       the file for read/write and obtain the file handle (DOS function
  545.       3DH will suffice).
  546.  
  547.       Once you have the file handle, you need a seven-byte block of
  548.       memory. Call DOS IOCTL function 4402H, as shown here:
  549.  
  550.       mov  BX,FileHandle
  551.       mov  Command,0AH
  552.       lds  DX,Command
  553.       mov  CX,7
  554.       mov  AX,4402H
  555.       int  21H
  556.       jc   error
  557.       cmp  AX,7
  558.       jne  read_error
  559.       ;
  560.       ; The byte at offset 1 of the seven-byte block of memory is the
  561.       ; number of the first track
  562.       ; The byte at offset 2 of the seven-byte block of memory is the
  563.       ; number of the last track
  564.       ; The dword at offset 4 of the seven-byte block of memory is the
  565.       ; start address of the first track in Red Book format
  566.  
  567.       On error (carry set), AX will hold an error code: 0001H (invalid
  568.       function), 0005H (access denied), 0006H (invalid handle), or
  569.       000DH (invalid data).
  570. ----------------------------------------------------------------------
  571. 6.02. What are Red Book and HSG formats?
  572.  
  573.       Both are ways of encoding frame information. An audio frame is
  574.       1/75 second of audio. HSG encodes frame information into a
  575.       double word: minute multiplied by 4500, plus second multiplied
  576.       by 75, plus frame, minus 150. Red Book encodes frame information
  577.       into a four-byte data structure:
  578.        Byte 0: frame number
  579.        Byte 1: second
  580.        Byte 2: minute
  581.        Byte 3: unused
  582. ----------------------------------------------------------------------
  583. 6.03. How can I determine where a particular track starts?
  584.  
  585.       First, you need the name of the device driver (see question
  586.       2.03, How do I get the name of the CD-ROM device driver?). Open
  587.       the file for read/write and obtain the file handle (DOS function
  588.       3DH will suffice).
  589.  
  590.       Once you have the file handle, you need an eight-byte block of
  591.       memory. Call DOS IOCTL function 4402H, as shown here:
  592.  
  593.       mov  BX,FileHandle
  594.       mov  Command,0BH
  595.       mov  Command+1,TrackNumber
  596.       lds  DX,Command
  597.       mov  CX,8
  598.       mov  AX,4402H
  599.       int  21H
  600.       jc   error
  601.       cmp  AX,8
  602.       jne  read_error
  603.       ;
  604.       ; The dword at offset 2 of the eight-byte block of memory is the
  605.       ; start address of the specified track in Red Book format
  606.       ; The word at offset 6 of the eight-byte block of memory is the
  607.       ; track control information. Bits 15-12 are used:
  608.       ; 0xxx: Two audio channels, no pre-emphasis, digital copy not
  609.       ;       permitted
  610.       ; 1xxx: Two audio channels, with pre-emphasis, digital copy not
  611.       ;       permitted
  612.       ; 2xxx: Two audio channels, no pre-emphasis, digital copy
  613.       ;       permitted
  614.       ; 3xxx: Two audio channels, with pre-emphasis, digital copy
  615.       ;       permitted
  616.       ; 4xxx: Data track, digital copy not permitted
  617.       ; 6xxx: Data track, digital copy permitted
  618.       ; 8xxx: Four audio channels, no pre-emphasis, digital copy not
  619.       ;       permitted
  620.       ; 9xxx: Four audio channels, with pre-emphasis, digital copy not
  621.       ;       permitted
  622.       ; Axxx: Four audio channels, no pre-emphasis, digital copy
  623.       ;       permitted
  624.       ; Bxxx: Four audio channels, with pre-emphasis, digital copy
  625.       ;       permitted
  626.  
  627.       On error (carry set), AX will hold an error code: 0001H (invalid
  628.       function), 0005H (access denied), 0006H (invalid handle), or
  629.       000DH (invalid data).
  630. ----------------------------------------------------------------------
  631. 6.04. How do I play audio?
  632.  
  633.       For starters, you need MSCDEX Version 2.1 or greater (see
  634.       question 1.02, How do I determine the MSCDEX version?).
  635.  
  636.       You also need the subunit number for the drive containing the
  637.       audio CD (see question 2.03, How do I get the name of the CD-ROM
  638.       device driver?)
  639.  
  640.       You also need to know what frame you want to start with (see
  641.       question 6.03, How can I determine where a particular track
  642.       starts?), and how many frames you want to play.
  643.  
  644.       Now, you need a 22-byte block of memory. Write 22 (16H) to the
  645.       first byte. Write the subunit number to the second byte. Write
  646.       84H to the third byte. Write 0 to the byte at offset 0DH (this
  647.       sets up HSG addressing). Convert the starting frame number to
  648.       HSG format and write the 4-byte result to the dword at offset
  649.       0EH. Finally, write the frame count to the dword at offset 12H.
  650.  
  651.       To play the CD as instructed, execute this code:
  652.  
  653.       les  BX,Buffer
  654.       mov  CX,Drive    ; must be in format 0 = A:, 1 = B:, etc.
  655.       mov  AX,1510H
  656.       int  2FH
  657.       ;
  658.       ; status is in the word at offset 3 of the buffer. Look for bit
  659.       ; 8 set (done), and watch out for bit 15 set (error).
  660.       ;
  661. ----------------------------------------------------------------------
  662. 6.05. How do I pause audio playback?
  663.  
  664.       For starters, you need MSCDEX Version 2.1 or greater (see
  665.       question 1.02, How do I determine the MSCDEX version?).
  666.  
  667.       You also need the subunit number for the drive containing the
  668.       audio CD (see question 2.03, How do I get the name of the CD-ROM
  669.       device driver?)
  670.  
  671.       Now, you need a 13-byte block of memory. Write 13 (0DH) to the
  672.       first byte. Write the subunit number to the second byte. Write
  673.       85H to the third byte.
  674.  
  675.       To pause the CD, execute this code:
  676.  
  677.       les  BX,Buffer
  678.       mov  CX,Drive    ; must be in format 0 = A:, 1 = B:, etc.
  679.       mov  AX,1510H
  680.       int  2FH
  681.       ;
  682.       ; status is in the word at offset 3 of the buffer. Look for bit
  683.       ; 8 set (done), and watch out for bit 15 set (error).
  684.       ;
  685. ----------------------------------------------------------------------
  686. 6.06. How do I resume audio playback?
  687.  
  688.       For starters, you need MSCDEX Version 2.1 or greater (see
  689.       question 1.02, How do I determine the MSCDEX version?).
  690.  
  691.       You also need the subunit number for the drive containing the
  692.       audio CD (see question 2.03, How do I get the name of the CD-ROM
  693.       device driver?)
  694.  
  695.       Now, you need a 13-byte block of memory. Write 13 (0DH) to the
  696.       first byte. Write the subunit number to the second byte. Write
  697.       88H to the third byte.
  698.  
  699.       To resume, execute this code:
  700.  
  701.       les  BX,Buffer
  702.       mov  CX,Drive    ; must be in format 0 = A:, 1 = B:, etc.
  703.       mov  AX,1510H
  704.       int  2FH
  705.       ;
  706.       ; status is in the word at offset 3 of the buffer. Look for bit
  707.       ; 8 set (done), and watch out for bit 15 set (error).
  708.       ;
  709.  
  710.  
  711.  
  712.