home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / listings / v_03_03 / 3n03030a < prev    next >
Text File  |  1992-02-08  |  34KB  |  1,055 lines

  1.         TITLE   CDCNTL  TSR TO CONTROL CD AUDIO PLAY   DSB
  2.  
  3. PSP_ENV      EQU     44                ;PSP OFFSET - ENVRN
  4. BELL         EQU     07H               ;BELL CHARACTER
  5. ESCKEY       EQU     27                ;ESCAPE KEY
  6.  
  7. ;*    EQUATES FOR DEVICE DRIVER COMMAND CODES             *
  8.  
  9. PLAY_CMD        EQU  132                ;PLAY AUDIO COMMAND
  10. READ_IOCTL_CMD  EQU  3                  ;READ IOCTL COMMAND
  11. STOP_CMD        EQU  133                ;STOP AUDIO COMMAND
  12. IOC_ADI_CMD     EQU  10                 ;AUDIO INFO IOCTL
  13. IOC_TIF_CMD     EQU  11                 ;TRACK INFO IOCTL
  14. IOC_ADS_CMD     EQU  6                  ;AUDIO STATUS IOCTL
  15. IOC_MDC_CMD     EQU  9                  ;MEDIA CHANGED IOCTL
  16. IOC_QIQ_CMD     EQU  12                 ;Q CHANNEL INQ IOCTL
  17.  
  18. ;*    LAYOUT OF DEVICE DRIVER HEADER.  THIS INFO SITS AT 0 *
  19. ;*     WITHIN THE DEVICE DRIVER.                           *
  20.  
  21. DEV_HDR      STRUC                 ;DEVICE DRIVER HEADER
  22. SDEV_NEXT    DD    ?                ;NEXT DEVICE DRIVER
  23. SDEV_ATT     DW    ?                ;DEVICE ATTRIBUTES
  24. SDEVSTRAT    DW    ?                ;OFFSET- STRATEGY ENTRY
  25. SDEVINT      DW    ?                ;OFFSET- INTERRUPT ENTRY
  26. SDEV_NAME    DB    8 DUP (?)        ;DEVICE NAME
  27. SDEV_RESV    DW    ?                ;RESERVED
  28. SDEV_LETR    DB    ?                ;1ST DRIVE LETTER
  29. SDEV_NUNT    DB    ?                ;NUMBER OF SUB UNITS
  30. DEV_HDR      ENDS
  31.  
  32. ;*    LAYOUT OF DEVICE DRIVE REQUEST PACKETS.  THE REQ HDR *
  33. ;*     IS ALWAYS PRESENT.  THIS IS IMMEDIATELY FOLLOWED BY *
  34. ;*     FUNCTION SPECIFIC INFORMATION.                      *
  35.  
  36. RQH          STRUC              ;DEVICE DRIVER REQ HDR
  37. RQH_LEN      DB    ?             ;LENGTH
  38. RQH_UNIT     DB    ?             ;UNIT ID
  39. RQH_CMD      DB    ?             ;COMMAND
  40. RQH_STATUS   DW    ?             ;STATUS
  41.  
  42. RQH_RSVD     DB    8 DUP (0)     ;RESERVED
  43. RQH          ENDS
  44.  
  45. RQP          STRUC              ;DATA FOLLOWING REQ HDR-PLAY
  46. RQP_ADDRMD   DB    0             ;ADDRESS MODE-HIGH SIERRA=0
  47.                                  ;             RED BOOK=1
  48. RQP_START    DD    ?             ;START ADDR FOR PLAY
  49. RQP_NUM      DD    ?             ;NUMBER TO PLAY
  50. RQP          ENDS
  51.  
  52. RQI          STRUC              ;DATA FOLLOWING REQ HDR-IOCTL
  53. RQI_MEDIA    DB    0             ;MEDIA - NOT USED
  54. RQI_XFER     DD    ?             ;POINTER TO CONTROL BLOCK
  55. RQI_NBYTES   DW    ?             ;LENGTH OF CONTROL BLOCK
  56. RQI_SECTOR   DW    0             ;SECTOR - NOT USED
  57. RQI_VOLID    DD    0             ;VOLID - NOT USED
  58. RQI          ENDS
  59.  
  60. ;*    CONTROL BLOCK LAYOUTS FOR VARIOUS IOCTL CALLS        *
  61.  
  62. IOS          STRUC                 ;CTRL BLK-IOCTL DVC STAT
  63. IOS_CMD      DB    6                ;COMMAND CODE
  64. IOS_STAT     DD    ?                ;DEVICE STATUS BITS
  65. IOS          ENDS
  66.  
  67. IOS_DOOR_OPEN   EQU  0001H          ;DOOR IS OPEN
  68. IOS_AUDIO_PLAY  EQU  0010H          ;AUDIO PLAY SUPPORTED
  69. IOS_RED_BOOK    EQU  0200H          ;HIGH SIERRA & RED BOOK
  70.  
  71. IOM          STRUC                 ;CTRL BLK-IOCTL MEDIA CHGD
  72. IOM_CMD      DB    9                ;COMMAND CODE
  73. IOM_MCHG     DB    ?                ;MEDIA CHANGED- 1 = NO
  74.                                     ;               0 = ??
  75.                                     ;              -1 = CHNGD
  76. IOM          ENDS
  77.  
  78. IOD          STRUC                 ;CTRL BLK-IOCTL AUDIO INFO
  79. IOD_CMD      DB    10               ;COMMAND CODE
  80. IOD_LOTNO    DB    ?                ;LOW TRACK NUMBER
  81. IOD_HITNO    DB    ?                ;HIGH TRACK NUMBER
  82. IOD_LEADOUT  DD    ?                ;ADDR LEADOUT (END AUDIO)
  83. IOD          ENDS
  84.  
  85.  
  86.  
  87. IOT          STRUC                 ;CTRL BLK-IOCTL TRACK 
  88. INFO
  89. IOT_CMD      DB    11               ;COMMAND CODE
  90. IOT_TNO      DB    ?                ;TRACK NUMBER
  91. IOT_START    DD    ?                ;TRACK START
  92. IOT_CTRL     DB    ?                ;CONTROL INFO
  93. IOT          ENDS
  94.  
  95. IOQ          STRUC                 ;CTRL BLK-IOCTL Q CHANNEL
  96. IOQ_CMD      DB    12               ;COMMAND CODE
  97. IOQ_CTRL     DB    ?                ;CONTROL INFO
  98. IOQ_TNO      DB    ?                ;TRACK NUMBER
  99. IOQ_INDX     DB    ?                ;INDEX OR POINT
  100. IOQ_MIN      DB    ?                ;MINUTES
  101. IOQ_SEC      DB    ?                ;SECONDS
  102. IOQ_FRAME    DB    ?                ;FRAMES
  103. IOQ_ZERO     DB    ?                ;ZERO
  104. IOQ_PMIN     DB    ?                ;P MINUTES
  105. IOQ_PSEC     DB    ?                ;P SECONDS
  106. IOQ_PFRAME   DB    ?                ;P FRAMES
  107. IOQ          ENDS
  108.  
  109. ;*    LAYOUT OF TRACK INFO ARRAY ENTRIES IN 'TOCINFO'      *
  110.  
  111. TOCI         STRUC                 ;TOC TRACK INFO ENTRIES
  112. TOC_TNO      DB    ?                ;TRACK NUMBER
  113. TOC_START    DD    ?                ;START ADDR
  114. TOCI         ENDS
  115.  
  116. DATA    SEGMENT PARA PUBLIC
  117.  
  118. STACKINT9 DW    256 DUP (?)     ;STACK USED FOR POPUP
  119. SVSPINT9 DW     ?               ;SAVE FOR STACK POINTER
  120. SVSSINT9 DW     ?               ;SAVE FOR STACK SEGMENT
  121. REGENADR DW     ?               ;VIDEO MEMORY SEG FOR I/O
  122.  
  123.                                 ;CURRENT CD INFO
  124. TNO     DB      0                 ;TRACK NUMBER
  125. TIMEM   DB      0                 ;MINUTE
  126. TIMES   DB      0                 ;SECONDS
  127. CLOSED  DB      0                 ;DOOR CURRENTLY CLOSED
  128.                                   ; 0 = NO, 1 = YES
  129.  
  130.  
  131.  
  132. TOCINFO TOCI    99 DUP (<>)     ;SPACE FOR 99 AUDIO TRACKS
  133. LOWTNO  DB      ?               ;LOW TRACK ON DISC
  134. HIGHTNO DB      ?               ;HIGH TRACK ON DISC
  135. ENDADDR DD      ?               ;ENDING ADDR
  136.  
  137. DEV_STRAT DD    ?               ;STRATEGY ENTRY POINT
  138. DEV_INT   DD    ?               ;INTERRUPT ENTRY POINT
  139. DEV_UNIT  DB    0               ;SUB UNIT ID
  140.  
  141.                                 ;DEVICE DRIVER REQ PACKET
  142. REQHDR  RQH     <>              ;REQUEST HEADER AREA
  143. REQFLW  RQI     <>              ;DATA FOLLOWING THE REQ HDR
  144.                                 ; (FUNCTION DEPENDENT)
  145.  
  146. IOCTLB  IOQ     <>              ;AREA FOR IOCTL CONTROL BLK
  147.  
  148. CVTWK   DW      ?               ;WORK AREA
  149.  
  150. POP_COLS      EQU    40
  151. POP_ROWS      EQU    12
  152. POP_START_ROW EQU    7
  153. POP_START_COL EQU    21
  154. POP_BG        EQU    30H
  155.             ;SAVE AREA FOR VIDEO MEMORY
  156. POP_SAVE    DW   POP_COLS*POP_ROWS DUP (?)
  157.  
  158. REGEN       LABEL DWORD
  159. REGENO      DW   4EH
  160. REGENS      DW   40H            ;ADDR OF VIDEO REGEN AREA
  161.  
  162. VMODE       LABEL DWORD
  163. VMODEO      DW   49H
  164. VMODES      DW   40H            ;ADDR OF VIDEO MODE
  165.  
  166. POP_IMG DB      ''
  167.         DB      '          CD-ROM AUDIO CONTROL        '
  168.         DB      '        CURRENT TRACK '
  169. P_TNO   DB      ' 0'
  170.         DB      '  '
  171. P_TIME  DB      5 DUP (' ')
  172.         DB      '       '
  173.         DB      '         SELECT A FUNCTION:           '
  174.         DB      '            P - Play                  '
  175.         DB      '            S - Stop                  '
  176.         DB      '            R - Resume                '
  177.         DB      '            N - Next                  '
  178.         DB      '            L - Prev                  '
  179.         DB      '           ESC- CLOSE WINDOW          '
  180.         DB      '                                      '
  181.         DB      ''
  182.  
  183.  
  184. DATA    ENDS
  185.  
  186. CODE    SEGMENT PARA PUBLIC
  187.         ASSUME  CS:CODE,DS:DATA
  188.  
  189. ;*              INT09H INTERRUPT HANDLER                   *
  190. ;*             DO POPUP ON SHIFT,SHIFT,CTRL                *
  191.  
  192. OLD_INT9 DD     ?               ;SAVED INT 09
  193. IN_POPUP DB     0               ;NON-ZERO IF POPUP ACTIVE
  194. SIG     DB      'CDCNTL'        ;SIGNITURE -
  195. SIGL    EQU     $-SIG            RIGHT BEFORE INT9 ENTRY
  196.  
  197. TRAP_KB PROC    FAR             ;PROCESS INT09 KEYBOARD HIT
  198.         CMP     IN_POPUP,0      ;CHK ALREADY IN POPUP
  199.         JE      NOTINPOP
  200.         JMP     OLD_INT9        ;CONT TO NEXT HANDLER-ACTIVE
  201. NOTINPOP:
  202.         MOV     IN_POPUP,1
  203.         PUSH    DS
  204.         PUSH    BX
  205.         MOV     BX,DATA
  206.         MOV     DS,BX           ;SET UP DS
  207.         MOV     SVSPINT9,SP     ;SAVE INCOMING SS:SP
  208.         MOV     BX,SS
  209.         MOV     SVSSINT9,BX
  210.         MOV     BX,DS
  211.         MOV     SS,BX           ;SWITCH TO LOCAL STACK
  212.         MOV     SP,OFFSET STACKINT9+SIZE STACKINT9-2
  213.         PUSH    AX
  214.         PUSH    CX
  215.         PUSH    DX
  216.         PUSH    DI
  217.         PUSH    SI
  218.         PUSH    ES
  219.         PUSH    BP
  220.         PUSHF
  221.         CALL    OLD_INT9         ;CALL OLD KEYBOARD ROUT
  222.         MOV     AH,2
  223.         INT     16H              ;GET SHIFT STATUS
  224.         AND     AL,07H
  225.         CMP     AL,07H           ;CHK FOR CTRL, SHIFT,SHIFT
  226.         JNE     KBRTN
  227.  
  228.         JMP     DOPOPUP
  229. KBRTN:
  230.         POP     BP
  231.         POP     ES
  232.         POP     SI
  233.         POP     DI
  234.         POP     DX
  235.         POP     CX
  236.         POP     AX
  237.         MOV     BX,SVSSINT9
  238.         CLI
  239.         MOV     SS,BX
  240.         MOV     SP,SVSPINT9     ;SWITCH BACK TO SAVED STACK
  241.         POP     BX
  242.         POP     DS
  243.         MOV     IN_POPUP,0
  244.         IRET
  245. DOPOPUP:
  246.         MOV     DX,0B800H
  247.         LES     BX,VMODE
  248.         MOV     AL,ES:[BX]      ;GET CURRENT VIDEO MODE
  249.         CMP     AL,2
  250.         JE      OKVIDEOM
  251.         CMP     AL,3
  252.         JE      OKVIDEOM
  253.         MOV     DX,0B000H
  254.         CMP     AL,7
  255.         JE      OKVIDEOM
  256.         JMP     KBRTN           ;IGNORE-NOT IN MODE 2,3,7
  257. OKVIDEOM:
  258.         CLD
  259.         LES     BX,REGEN
  260.         MOV     AX,ES:[BX]      ;GET START VIDEO REGEN AREA
  261.         MOV     CL,4
  262.         SHR     AX,CL           ;CALC PARAGRAPH
  263.         ADD     AX,DX           ;ADD BASE VIDEO SEGMENT
  264.         MOV     REGENADR,AX     ;SAVE SEGMENT FOR VIDEO I/O
  265.         MOV     ES,AX
  266.         MOV     AX,POP_START_ROW
  267.         DEC     AX
  268.         MOV     CX,160          ;BYTES/ROW OF VIDEO MEMORY
  269.         MUL     CL
  270.         MOV     SI,AX
  271.         MOV     AX,POP_START_COL
  272.         DEC     AX
  273.         SHL     AX,1            ;2 BTYES/COL
  274.         ADD     SI,AX           ;1ST MEMORY AREA TO SAVE
  275.         MOV     DI,OFFSET POP_SAVE
  276.         PUSH    DS
  277.         PUSH    ES
  278.         POP     DS
  279.         POP     ES
  280.         MOV     CX,POP_ROWS     ;NUMBER OF ROWS TO SAVE
  281. SAVVID:
  282.         PUSH    CX
  283.         PUSH    SI
  284.  
  285.         MOV     CX,POP_COLS     ;NUMBER OF COLS TO SAVE
  286.         REP     MOVSW           ;SAVE ROW OF VIDEO
  287.         POP     SI
  288.         POP     CX
  289.         ADD     SI,160          ;GO NEXT ROW
  290.         LOOP    SAVVID
  291.         MOV     AX,DATA
  292.         MOV     DS,AX           ;RESTORE DS
  293.         CALL    FILL_CHECKING   ;SHOW CHECKING STATUS
  294. CALLPOP:                        ;  ***MAIN INPUT LOOP***
  295.         CALL    PUT_POP
  296.         MOV     AH,1
  297.         INT     16H             ;CHK KEYSTROKE WAITING
  298.         JNZ     KEYIN
  299.         CALL    CHKCHG          ;GET CURRENT AUDIO STATUS
  300.         MOV     AL,TNO
  301.         MOV     SI,OFFSET P_TNO
  302.         CALL    CVHEX           ;CONVERT TRACK NUMBER
  303.         PUSH    DS
  304.         POP     ES
  305.         MOV     DI,OFFSET P_TIME
  306.         MOV     AL,' '
  307.         MOV     CX,SIZE P_TIME
  308.         REP     STOSB           ;CLEAR TIME AREA
  309.         CMP     TNO,0
  310.         JE      DUNTIMEZ
  311.         MOV     AL,TIMEM
  312.         MOV     SI,OFFSET P_TIME
  313.         CALL    CVHEX           ;CONVERT MINUTES
  314.         MOV     AL,TIMES
  315.         MOV     SI,OFFSET P_TIME+3
  316.         CALL    CVHEX
  317.         CMP     P_TIME+3,' '
  318.         JNE     DUNTIME
  319.         MOV     P_TIME+3,'0'    ;ZERO FILL SECONDS
  320. DUNTIME:
  321.         MOV     P_TIME+2,':'
  322. DUNTIMEZ:
  323.         JMP     CALLPOP         ;CONTINUE TO UPDATE POPUP INFO
  324. KEYIN:                          ;PROCESS KEYSTROKE
  325.         MOV     AH,0
  326.         INT     16H             ;GET QUEUED KEYSTROKE
  327.         CMP     AL,ESCKEY
  328.         JNE     FCT_IN
  329. GORESTV:
  330.         JMP     REST_VIDEO
  331. FCT_IN:
  332.         OR      AL,20H          ;MAKE LOWER CASE
  333.         CMP     AL,'p'          ;CHK FOR SUPPORTED FCTS
  334.         JE      CHK_FCTIN
  335.         CMP     AL,'s'
  336.         JE      CHK_FCTIN
  337.         CMP     AL,'r'
  338.         JE      CHK_FCTIN
  339.         CMP     AL,'n'
  340.  
  341.         JE      CHK_FCTIN
  342.         CMP     AL,'l'
  343.         JE      CHK_FCTIN
  344. BELL_AGAIN:
  345.         MOV     AL,BELL
  346.         MOV     AH,0EH
  347.         INT     10H
  348.         JMP     CALLPOP
  349. CHK_FCTIN:
  350.         CMP     CLOSED,0        ;CHK DOOR OPEN
  351.         JNE     DOOR_CLOSED
  352.         JMP     BELL_AGAIN
  353. DOOR_CLOSED:
  354.         CMP     AL,'p'          ;CHK PLAY
  355.         JNE     NOT_PLAY
  356.         MOV     AL,LOWTNO       ;START WITH LOW TRACK#
  357. CALL_PLAY:
  358.         CALL    PLAY            ;PLAY AUDIO
  359.         OR      AX,AX
  360.         JNZ     BELL_AGAIN
  361.         JMP     CALLPOP
  362. NOT_PLAY:
  363.         CMP     AL,'r'          ;CHK RESUME
  364.         JNE     NOT_RESUME
  365.         CALL    RESUME          ;RESUME PLAY
  366.         OR      AX,AX
  367.         JNZ     BELL_AGAIN
  368.         JMP     CALLPOP
  369. NOT_RESUME:
  370.         CMP     AL,'s'          ;CHK STOP
  371.         JNE     NOT_STOP
  372.         CALL    STOP            ;STOP PLAYING
  373.         JMP     CALLPOP
  374. NOT_STOP:
  375.         CMP     AL,'n'          ;CHK NEXT TRACK
  376.         JNE     NOT_NEXT
  377.         CMP     LOWTNO,0
  378.         JE      BELL_AGAIN
  379.         MOV     AL,TNO
  380.         OR      AL,AL
  381.         JZ      BELL_AGAIN
  382.         INC     AL
  383.         CMP     AL,HIGHTNO      ;CHK THERE IS A NEXT TRACK
  384.         JG      BELL_AGAIN
  385.         JMP     CALL_PLAY
  386. NOT_NEXT:                       ;PREV TRACK REQUEST
  387.         CMP     LOWTNO,0
  388.         JE      BELL_AGAIN
  389.         MOV     AL,TNO
  390.         OR      AL,AL
  391.  
  392.         JZ      BELL_AGAIN
  393.         DEC     AL
  394.         CMP     AL,LOWTNO       ;CHK THERE IS A PREV TRACK
  395.         JL      BELL_AGAIN
  396.         JMP     CALL_PLAY
  397. REST_VIDEO:                     ;RESTORE SAVE VIDEO IMAGE
  398.         MOV     AX,REGENADR
  399.         MOV     ES,AX
  400.         MOV     AX,POP_START_ROW
  401.         DEC     AX
  402.         MOV     CX,160          ;BYTES/ROW OF VIDEO MEMORY
  403.         MUL     CL
  404.         MOV     DI,AX
  405.         MOV     AX,POP_START_COL
  406.         DEC     AX
  407.         SHL     AX,1            ;2 BTYES/COL
  408.         ADD     DI,AX           ;1ST MEMORY AREA TO RESTORE
  409.         MOV     SI,OFFSET POP_SAVE
  410.         MOV     CX,POP_ROWS     ;NUMBER OF ROWS SAVED
  411. RESTVID:
  412.         PUSH    CX
  413.         PUSH    DI
  414.         MOV     CX,POP_COLS     ;NUMBER OF COLS TO REST
  415.         REP     MOVSW           ;REST ROW OF VIDEO
  416.         POP     DI
  417.         POP     CX
  418.         ADD     DI,160          ;GO NEXT ROW
  419.         LOOP    RESTVID
  420.         JMP     KBRTN
  421. TRAP_KB ENDP
  422.  
  423. ;*              ROUTINE TO CONVERT NUMBER IN AL TO DS:SI   *
  424. ;*                INPUT IS IN BINARY                       *
  425. ;*                CONVERTED TO ASCII CHARACTERS            *
  426.  
  427. CVHEX   PROC
  428.         PUSH    AX
  429.         OR      AL,AL           ;CHK ZERO
  430.         JNZ     CVHEXA
  431.         MOV     AX,'0 '
  432.         JMP     CVHEXZ
  433. CVHEXA:
  434.         MOV     AH,0
  435.         PUSH    CX
  436.         MOV     CL,10
  437.         DIV     CL
  438.         ADD     AX,'00'         ;DISPLAY IN ASCII
  439.         POP     CX
  440.         CMP     AL,'0'
  441.  
  442.         JNE     CVHEXZ
  443.         MOV     AL,' '          ;BLANK 1ST DIGIT IF ZERO
  444. CVHEXZ:
  445.         MOV     [SI],AX         ;MOVE TO OUTPUT POSITION
  446.         POP     AX
  447.         RET
  448. CVHEX   ENDP
  449.  
  450. ;* ROUTINE TO FILL POPUP TO SHOW CHECKING DISC STATUS      *
  451.  
  452. FILL_CHECKING   PROC
  453.         MOV     WORD PTR P_TNO,'0 '     ;TRACK ZERO
  454.         MOV     WORD PTR P_TIME,'AW'    ;FILL 'WAIT'
  455.         MOV     WORD PTR P_TIME+2,'TI'
  456.         MOV     P_TIME+4,' '
  457.         RET
  458. FILL_CHECKING   ENDP
  459.  
  460. ;* ROUTINE TO PAINT THE POPUP TO THE SCREEN                *
  461.  
  462. PUT_POP PROC
  463.         MOV     AX,REGENADR
  464.         MOV     ES,AX
  465.         MOV     AX,POP_START_ROW
  466.         DEC     AX
  467.         MOV     CX,160          ;BYTES/ROW OF VIDEO MEMORY
  468.         MUL     CL
  469.         MOV     DI,AX
  470.         MOV     AX,POP_START_COL
  471.         DEC     AX
  472.         SHL     AX,1            ;2 BTYES/COL
  473.         ADD     DI,AX           ;1ST MEMORY AREA TO PAINT
  474.         MOV     SI,OFFSET POP_IMG
  475.         MOV     CX,POP_ROWS     ;NUMBER OF ROWS TO PAINT
  476. PUTVIDA:
  477.         PUSH    CX
  478.         PUSH    DI
  479.         MOV     CX,POP_COLS     ;NUMBER OF COLS TO PAINT
  480. PUTVIDB:
  481.         LODSB
  482.         MOV     AH,POP_BG       ;ATTRIBUTE
  483.         STOSW
  484.         LOOP    PUTVIDB
  485.         POP     DI
  486.         POP     CX
  487.         ADD     DI,160          ;GO NEXT ROW
  488.  
  489.         LOOP    PUTVIDA
  490.         RET
  491. PUT_POP ENDP
  492.  
  493.         PAGE
  494.  
  495. ;* ROUTINE TO DO AN IOCTL CALL                             *
  496. ;* MUST FILL IOCTL CONTROL BLOCK AND LTH TO RQI_NBTYES     *
  497. ;* AX RETURN NON-ZERO WITH STATUS IF ERROR OCCURS          *
  498.  
  499. IOCTL   PROC
  500.         PUSH    ES
  501.         PUSH    BX
  502.         MOV     REQHDR.RQH_LEN,TYPE RQH + TYPE RQI ;LTH REQ
  503.         MOV     AL,DEV_UNIT
  504.         MOV     REQHDR.RQH_UNIT,AL      ;SUB UNIT ID
  505.         MOV     REQHDR.RQH_CMD,READ_IOCTL_CMD ;READ IOCTL
  506.         MOV     REQHDR.RQH_STATUS,0
  507.         MOV     REQFLW.RQI_MEDIA,0      ;MEDIA - NOT USED
  508.         MOV     REQFLW.RQI_SECTOR,0     ;SECTOR - NOT USED
  509.         MOV     WORD PTR REQFLW.RQI_VOLID,0 ;VOLID - UNUSED
  510.         MOV     WORD PTR REQFLW.RQI_VOLID+2,0
  511.         PUSH    DS
  512.         POP     WORD PTR REQFLW.RQI_XFER+2 ;ADDR OF CTL BLK
  513.         MOV     WORD PTR REQFLW.RQI_XFER,OFFSET IOCTLB
  514.         PUSH    DS
  515.         POP     ES
  516.         MOV     BX,OFFSET REQHDR  ;POINT ES:BX TO REQ HDR
  517.         CALL    CALL_DVC          ;CALL DEVICE DRIVER
  518.         POP     BX                ; ERROR CODE IN AX
  519.         POP     ES
  520.         RET
  521. IOCTL   ENDP
  522.  
  523. ;*  CALL DEVICE DRIVER.  ES:BX POINTS TO REQUEST PACKET.   *
  524. ;*              AX RETURNS 0 IF OK, ELSE ERROR CODE.       *
  525.  
  526. CALL_DVC PROC
  527.         CALL    DEV_STRAT       ;CALL STATEGY ENTRY
  528.         CALL    DEV_INT         ;CALL INTERRUPT ENTRY
  529.         MOV     AX,0            ;SHOW NO ERROR
  530.         TEST    REQHDR.RQH_STATUS,8000H  ;CHK ERROR
  531.         JZ      CALL_DVCZ
  532.         MOV     AX,REQHDR.RQH_STATUS
  533. CALL_DVCZ:
  534.         RET
  535. CALL_DVC ENDP
  536.  
  537.  
  538.  
  539.  
  540. ;*      ROUTINE TO FILL THE TOC INFO TO TOCINFO            *
  541. ;*              RETURN AX NON-ZERO IF ERROR                *
  542.  
  543. TOC     PROC
  544.         PUSH    CX
  545.         PUSH    SI
  546.         MOV     LOWTNO,0        ;INDICATES NO DISC
  547.         MOV     IOCTLB.IOD_CMD,IOC_ADI_CMD ;FILL CTRL BLK-
  548.         MOV     REQFLW.RQI_NBYTES,TYPE IOD ; AUDIO DISK INFO
  549.         CALL    IOCTL                      ;GET AUDIO INFO
  550.         OR      AX,AX
  551.         JNZ     TOCZ
  552.         MOV     AL,IOCTLB.IOD_LOTNO     ;GET LOW, HIGH TNOS
  553.         MOV     LOWTNO,AL
  554.         MOV     AL,IOCTLB.IOD_HITNO
  555.         MOV     HIGHTNO,AL
  556.         MOV     AX,WORD PTR IOCTLB.IOD_LEADOUT  ;GET END
  557.         MOV     WORD PTR ENDADDR,AX             ; ADDRESS
  558.         MOV     AX,WORD PTR IOCTLB.IOD_LEADOUT+2
  559.         MOV     WORD PTR ENDADDR+2,AX
  560.         MOV     SI,OFFSET TOCINFO       ;FILL TRACK INFO
  561.         MOV     CL,LOWTNO
  562.         MOV     IOCTLB.IOT_CMD,IOC_TIF_CMD
  563.         MOV     REQFLW.RQI_NBYTES,TYPE IOT
  564. TOCA:
  565.         CMP     CL,HIGHTNO              ;CHK FINISHED
  566.         JNG     TOCB
  567.         MOV     AX,0
  568.         JMP     TOCZ
  569. TOCB:
  570.         MOV     IOCTLB.IOT_TNO,CL
  571.         CALL    IOCTL                   ;DO IOCTL-TRACK INFO
  572.         OR      AX,AX
  573.         JZ      TOCC
  574.         MOV     LOWTNO,0                ;MARK NO DISC IF ERR
  575.         JMP     TOCZ
  576. TOCC:
  577.         MOV     [SI].TOC_TNO,CL         ;FILL TRACK NUMBER
  578.         MOV     AX,WORD PTR IOCTLB.IOT_START
  579.         MOV     WORD PTR [SI].TOC_START,AX      ;START ADDR
  580.         MOV     AX,WORD PTR IOCTLB.IOT_START+2
  581.         MOV     WORD PTR [SI].TOC_START+2,AX
  582.         ADD     SI,TYPE TOCI             ;GO NEXT TRACK
  583.         INC     CL
  584.         JMP     TOCA
  585. TOCZ:
  586.         POP     SI
  587.         POP     CX
  588.         RET
  589. TOC     ENDP
  590.  
  591.  
  592.  
  593.  
  594. ;*        ROUTINE TO GET CURRENT STATUS OF DISC            *
  595. ;*        REREAD TOC IF NEEDED.  AX RETURN NON-ZERO IF ERR *
  596.  
  597. CHKCHG  PROC
  598.         PUSH    BX
  599.         PUSH    DX
  600.         MOV     TNO,0           ;INDICATES NO DISC OR ERROR
  601.         MOV     TIMEM,0
  602.         MOV     TIMES,0
  603.         MOV     CLOSED,0
  604.         MOV     IOCTLB.IOS_CMD,IOC_ADS_CMD ;SET FOR DEVICE
  605.         MOV     REQFLW.RQI_NBYTES,TYPE IOS ; STATUS IOCTL
  606.         CALL    IOCTL                      ;DO IOCTL
  607.         OR      AX,AX
  608.         JZ      CHKCHGA
  609.         JMP     CHKCHGZ
  610. CHKCHGA:
  611.         TEST    WORD PTR IOCTLB.IOS_STAT,IOS_DOOR_OPEN
  612.         JZ      CHKCHGB
  613.         JMP     CHKCHGZ         ;RETURN - DOOR OPEN
  614. CHKCHGB:
  615.         MOV     CLOSED,1        ;DOOR IS CLOSED
  616.         CALL    Q_INQ           ;DO A Q CHANNEL INQ
  617.         OR      AX,AX
  618.         JZ      CHKCHGC
  619.         JMP     CHKCHGZ         ;LEAVE IF ERROR
  620. CHKCHGC:
  621.         MOV     TNO,DH          ;FILL TRACK,
  622.         MOV     TIMEM,DL        ; MINUTES AND SECONDS
  623.         MOV     TIMES,BH
  624.         CMP     TNO,0           ;CHK PLAYING
  625.         JE      CHKCHGF
  626.         JMP     CHKCHGZ         ; YES - RETURN
  627. CHKCHGF:
  628.         MOV     IOCTLB.IOM_CMD,IOC_MDC_CMD ;SET FOR
  629.         MOV     REQFLW.RQI_NBYTES,TYPE IOM ; IOCTL MEDIA CHNG
  630.         CALL    IOCTL
  631.         OR      AX,AX
  632.         JZ      CHKCHGG
  633.         JMP     CHKCHGZ
  634. CHKCHGG:
  635.         CMP     IOCTLB.IOM_MCHG,1       ;CHK MEDIA NOT CHNGD
  636.         JNE     CHKCHGH
  637.         JMP     CHKCHGZ                 ; NO - RETURN
  638. CHKCHGH:
  639.         CALL    FILL_CHECKING           ; YES - GET READY
  640.         CALL    PUT_POP                 ;  TO RE-READ TOC
  641.         CALL    TOC                     ;RE READ TOC
  642.         MOV     TNO,0
  643.  
  644.         MOV     TIMEM,0
  645.         MOV     TIMES,0
  646.         CALL    Q_INQ                   ;DO Q CHAN INQ
  647.         OR      AX,AX                   ; AFTER TOC
  648.         JZ      CHKCHGI
  649.         JMP     CHKCHGZ
  650. CHKCHGI:
  651.         MOV     TNO,DH
  652.         MOV     TIMEM,DL
  653.         MOV     TIMES,BH
  654.         MOV     AX,0
  655. CHKCHGZ:
  656.         POP     DX
  657.         POP     BX
  658.         RET
  659. CHKCHG  ENDP
  660.  
  661. ;*      DO Q CHANNEL INQ.                                  *
  662. ;*   AX RETURNS ZERO IF SUCCESSFUL                         *
  663. ;*   IF SUCCESSFUL - DH = TNO, DL = MINUTES, BH = SECONDS, *
  664. ;*                              BL = FRAME                 *
  665.  
  666. Q_INQ   PROC
  667.         MOV     IOCTLB.IOQ_CMD,IOC_QIQ_CMD ;SET FOR
  668.         MOV     REQFLW.RQI_NBYTES,TYPE IOQ ; Q CHANNEL INQ
  669.         CALL    IOCTL
  670.         OR      AX,AX
  671.         JZ      Q_INQA
  672.         RET                     ;RETURN ERROR
  673. Q_INQA:
  674.         MOV     AL,IOCTLB.IOQ_TNO
  675.         CALL    CVTTNO          ;CONVERT TNO TO BINARY
  676.         MOV     DH,AL           ;FILL TRACK, MIN, SEC
  677.         MOV     DL,IOCTLB.IOQ_MIN
  678.         MOV     BH,IOCTLB.IOQ_SEC
  679.         MOV     BL,IOCTLB.IOQ_FRAME
  680.         XOR     AX,AX
  681.         RET
  682. Q_INQ   ENDP
  683.  
  684. ;*    CONVERT BCD IN AL TO BINARY IN AX                    *
  685.  
  686. CVTTNO  PROC
  687.         PUSH    BX
  688.         PUSH    CX
  689.         MOV     BL,AL
  690.  
  691.         AND     BL,0FH          ;GET LOW NIBBLE TO BL
  692.         MOV     CL,4
  693.         SHR     AL,CL           ;GET HIGH NIBBLE TO AL
  694.         MOV     CL,10
  695.         MUL     CL
  696.         MOV     BH,0            ;MULT HIGH NIBBLE BY 10
  697.         ADD     AX,BX
  698.         POP     CX              ;COMBINE NIBBLES
  699.         POP     BX
  700.         RET
  701. CVTTNO  ENDP
  702.  
  703. ;*      HIGH-LEVEL PLAY ROUTINE                             *
  704. ;*        START TRACK IN AL                                 *
  705. ;*        AX RETURN NON-ZERO IF ERROR                       *
  706.  
  707. PLAY    PROC
  708.         PUSH    SI
  709.         PUSH    CX
  710.         PUSH    ES
  711.         PUSH    BX
  712.         CMP     AL,LOWTNO       ;CHK GOOD TRACK NUMBER
  713.         JL      PLAYA
  714.         CMP     AL,HIGHTNO
  715.         JNA     PLAYB
  716. PLAYA:
  717.         MOV     AX,1
  718.         JMP     PLAYZ
  719. PLAYB:
  720.         MOV     SI,OFFSET TOCINFO
  721. PLAYC:
  722.         CMP     AL,[SI].TOC_TNO ;LOOK UP TRACK NUMBER
  723.         JE      PLAYD
  724.         ADD     SI,TYPE TOCI
  725.         JMP     PLAYC
  726. PLAYD:
  727.         MOV     AX,WORD PTR [SI].TOC_START  ;START ADDR
  728.         MOV     BX,WORD PTR [SI].TOC_START+2 ; TO BX:AX
  729.         CALL    CVTHSG          ;CONVERT TO HIGH SIERRA
  730.         CALL    PLAYLOW         ;GO PLAY FROM BX:AX TO END
  731. PLAYZ:
  732.         POP     BX
  733.         POP     ES
  734.         POP     CX
  735.         POP     SI
  736.         RET
  737. PLAY    ENDP
  738.  
  739.  
  740.  
  741. ;*      LOW-LEVEL PLAY ROUTINE                             *
  742. ;* PLAY FROM ADDR IN BX:AX (HIGH SIERRA FMT) TO LAST SECT  *
  743. ;*              AX RETURNED NON-ZERO IF ERROR              *
  744.  
  745. PLAYLOW PROC
  746.         PUSH    DX
  747.         PUSH    SI
  748.         PUSH    CX
  749.         PUSH    ES
  750.         PUSH    AX
  751.         CALL    STOP
  752.         POP     AX
  753.         MOV     REQHDR.RQH_LEN,TYPE RQH+TYPE RQP ;LTH PACKET
  754.         MOV     DL,DEV_UNIT
  755.         MOV     REQHDR.RQH_UNIT,DL      ;SUB UNIT ID
  756.         MOV     REQHDR.RQH_CMD,PLAY_CMD ;PLAY COMMAND
  757.         MOV     REQHDR.RQH_STATUS,0
  758.         MOV     REQFLW.RQP_ADDRMD,0     ;HIGH SIERRA MODE
  759.         MOV     WORD PTR REQFLW.RQP_START+2,BX
  760.         MOV     WORD PTR REQFLW.RQP_START,AX  ;FILL START
  761.         PUSH    BX
  762.         PUSH    AX
  763.         MOV     BX,WORD PTR ENDADDR+2
  764.         MOV     AX,WORD PTR ENDADDR
  765.         CALL    CVTHSG          ;CONVERT END ADDR
  766.         POP     SI              ; (BX:AX) TO HIGH SIERRA
  767.         POP     CX              ;GET START(HIGH SIERRA)-CX:SI
  768.         SUB     AX,SI           ;CALC NUMBER FRAMES
  769.         SBB     BX,CX
  770.         MOV     WORD PTR REQFLW.RQP_NUM,AX  ;FILL NUM
  771.         MOV     WORD PTR REQFLW.RQP_NUM+2,BX
  772.         PUSH    DS
  773.         POP     ES
  774.         MOV     BX,OFFSET REQHDR        ;ES:BX TO REQ HDR
  775.         CALL    CALL_DVC                ;START AUDIO PLAY
  776. PLAYLOWZ:
  777.         POP     ES
  778.         POP     CX
  779.         POP     SI
  780.         POP     DX
  781.         RET
  782. PLAYLOW ENDP
  783.  
  784. ;*              ROUTINE TO STOP AUDIO                      *
  785. ;*              AX RETURN NON-ZERO IF ERROR                *
  786.  
  787. STOP    PROC
  788.         PUSH    ES
  789.         PUSH    BX
  790.         MOV     REQHDR.RQH_LEN,TYPE RQH ;SIZE OF HEADER
  791.         MOV     AL,DEV_UNIT
  792.  
  793.         MOV     REQHDR.RQH_UNIT,AL      ;SUB UNIT ID
  794.         MOV     REQHDR.RQH_CMD,STOP_CMD ;STOP COMMAND
  795.         MOV     REQHDR.RQH_STATUS,0
  796.         PUSH    DS
  797.         POP     ES
  798.         MOV     BX,OFFSET REQHDR        ;ES:BX TO REQ HDR
  799.         CALL    CALL_DVC                ;CALL DEVICE DRIVER
  800.         POP     BX
  801.         POP     ES
  802.         RET
  803. STOP    ENDP
  804.  
  805. ;*              ROUTINE TO RESUME AUDIO                    *
  806. ;*              AX RETURN NON-ZERO IF ERROR                *
  807.  
  808. RESUME  PROC
  809.         PUSH    ES
  810.         PUSH    BX
  811.         PUSH    DX
  812.         PUSH    SI
  813.         CALL    Q_INQ           ;GET Q CHANNEL INFO TO DX:BX
  814.         OR      AX,AX
  815.         JZ      RESUMEB
  816.         JMP     RESUMEZ
  817. RESUMEB:
  818.         CMP     DH,0            ;CHK TNO == 0
  819.         JNE     RESUMEC         ; YES - CAN'T RESUME
  820.         MOV     AX,1
  821.         JMP     RESUMEZ
  822. RESUMEC:
  823.         MOV     AX,BX
  824.         MOV     BX,DX           ;GET CURRENT POS TO BX:AX
  825.         CALL    CVTHSG          ;CONVERT TO HIGH SIERRA
  826.                                 ; THIS IS OFFSET INTO TRACK
  827.         CMP     DH,LOWTNO       ;CHK GOOD TRACK NUMBER
  828.         JL      RESUMED
  829.         CMP     DH,HIGHTNO
  830.         JNA     RESUMEE
  831. RESUMED:
  832.         MOV     AX,1
  833.         JMP     RESUMEZ
  834. RESUMEE:
  835.         PUSH    AX
  836.         PUSH    BX              ;SAVE HIGH SIERRA OFFSET
  837.         MOV     SI,OFFSET TOCINFO
  838. RESUMEF:
  839.         CMP     DH,[SI].TOC_TNO ;LOOK UP TRACK NUMBER
  840.         JE      RESUMEG
  841.         ADD     SI,TYPE TOCI
  842.         JMP     RESUMEF
  843.  
  844.  
  845. RESUMEG:
  846.         MOV     AX,WORD PTR [SI].TOC_START ;START ADDR-BX:AX
  847.         MOV     BX,WORD PTR [SI].TOC_START+2
  848.         CALL    CVTHSG          ;CONVERT IT TO HIGH SIERRA
  849.         POP     DX
  850.         POP     SI              ;GET SAVED OFFSET TO DX:SI
  851.         ADD     AX,SI
  852.         ADC     BX,DX           ;ADD TO FRONT OF TRACK
  853.         CALL    PLAYLOW         ;PLAY FROM HERE TO END
  854. RESUMEZ:
  855.         POP     SI
  856.         POP     DX
  857.         POP     BX
  858.         POP     ES
  859.         RET
  860. RESUME  ENDP
  861.  
  862. ;* ROUTINE TO CONVERT REDBOOK TO HIGH SIERRA ADDR IN       *
  863. ;*      BX:AX                                              *
  864. ;* REDBOOK INPUT:  BL=MINUTES, AH=SECONDS, AL=FRAMES       *
  865. ;* HIGH SIERRA = ((MINUTES * 60) + SECONDS) * 75 + FRAMES  *
  866.  
  867. CVTHSG  PROC
  868.         PUSH    CX
  869.         PUSH    DX
  870.         PUSH    AX      ;SAVE LOW ORDER
  871.         MOV     BH,0    ;MSB SHOULD BE ZERO
  872.         MOV     AX,BX
  873.         MOV     CL,60
  874.         MUL     CL      ;GET SECONDS TO AX
  875.         POP     BX      ;GET LOW ORDER
  876.         PUSH    BX
  877.         MOV     BL,BH   ;GET SECONDS
  878.         MOV     BH,0
  879.         ADD     AX,BX   ;ADD SECONDS
  880.         MOV     CX,75
  881.         MUL     CX      ;GET FRAMES TO DX:AX
  882.         POP     BX
  883.         MOV     BH,0    ;GET FRAMES
  884.         ADD     AX,BX   ;ADD FRAMES
  885.         ADC     DX,0
  886.         MOV     BX,DX   ;GET RESULT TO BX:AX
  887.         POP     DX
  888.         POP     CX
  889.         RET
  890. CVTHSG  ENDP
  891.  
  892. KEEP_MEM LABEL  BYTE    ;MEMORY BELOW DISCARDED ON TSR
  893.  
  894.  
  895.  
  896.  
  897.         PAGE
  898.  
  899. ;*   ROUTINE TO INSTALL CDCNTL                             *
  900. ;*   THIS ROUTINE GETS CONTROL WHEN CDCNTL CALLED FROM DOS *
  901.  
  902. PSP     DW      ?       ;TEMP SAVE FOR PSP VALUE
  903.  
  904. DEVNAME DB      'CDROM1',0       ;DEVICE TO OPEN
  905.  
  906.  
  907. INSTALL_MSG DB  'CD-ROM AUDIO CONTROL',0DH,0AH
  908.             DB  'DEPRESS LEFT CTRL AND BOTH SHIFTS TO '
  909.             DB  ' ACTIVATE',0DH,0AH,'$'
  910. STATE_MSG   DB  'CDCNTL ALREADY INSTALLED - IGNORED.'
  911.             DB  0DH,0AH,BELL,'$'
  912. INSUFDD     DB  'DEVICE DRIVER DOES NOT SUPPORT AUDIO '
  913.             DB  'PLAY COMMANDS - CDCNTL'
  914.             DB  ' NOT INSTALLED!',0DH,0AH,BELL,'$'
  915. BADFIOCTL   DB  'ERROR ON IOCTL - CDCNTL NOT INSTALLED!'
  916.             DB  0DH,0AH,BELL,'$'
  917. ERROPEN_MSG DB  'UNABLE TO OPEN CDROM1 DEVICE - CDCNTL '
  918.             DB  'NOT INSTALLED!'
  919.             DB  0DH,0AH,BELL,'$'
  920. IOCTL_PACKET DB 0       ;GET DEVICE HEADER ADDR COMMAND
  921. IOCTL_PACKAD DD ?       ;DEVICE DRIVER ADDRESS FILLED HERE
  922. IOCTL_PACKETL EQU  $-IOCTL_PACKET
  923.  
  924.  
  925. CDCNTL  PROC    FAR
  926.         CLD
  927.         MOV     AX,DATA
  928.         MOV     DS,AX
  929.         MOV     PSP,ES          ;SAVE PSP SEGMENT
  930.         MOV     AX,3509H
  931.         INT     21H             ;GET CURRENT INT09H
  932.         MOV     DI,BX
  933.         SUB     DI,SIGL         ;BACKUP UP TO SIG AREA
  934.         MOV     SI,OFFSET SIG
  935.         MOV     CX,SIGL
  936.         PUSH    DS
  937.         PUSH    CS
  938.         POP     DS
  939.         REP     CMPSB           ;CHK ALREADY INSTALLED
  940.         POP     DS
  941.         JE      PUTSTATE
  942.         JMP     DOINSTALL
  943.  
  944. PUTSTATE:
  945.  
  946.         MOV     DX,OFFSET STATE_MSG
  947.         MOV     BL,1    ;END ERRORLEVEL 1-ALREADY INSTALLED
  948. ERROR_OUT:
  949.         PUSH    DS
  950.         PUSH    CS
  951.         POP     DS
  952.         MOV     AH,9
  953.         INT     21H             ;ALREADY INSTALLED MSG
  954.         POP     DS
  955.         MOV     AH,4CH
  956.         MOV     AL,BL
  957.         INT     21H             ;NORM EOJ-ERROR LEVEL SET
  958. DOINSTALL:
  959.         PUSH    ES              ;SAVE INT9 VECTOR VALUE
  960.         PUSH    BX
  961.         MOV     DX,OFFSET DEVNAME
  962.         MOV     AX,3D00H
  963.         PUSH    DS
  964.         PUSH    CS
  965.         POP     DS
  966.         INT     21H             ;TRY TO OPEN CDROM DEVICE
  967.         POP     DS
  968.         JNC     OKDEV_OPEN
  969.         MOV     DX,OFFSET ERROPEN_MSG
  970.         MOV     BL,2            ;ERRORLEVEL 2-CANT OPEN
  971.         JMP     ERROR_OUT
  972. OKDEV_OPEN:
  973.         MOV     BX,AX           ;HANDLE TO DEVICE
  974.         MOV     DX,OFFSET IOCTL_PACKET
  975.         MOV     CX,IOCTL_PACKETL
  976.         MOV     AX,4402H
  977.         PUSH    DS
  978.         PUSH    CS
  979.         POP     DS
  980.         INT     21H             ;DO GENERIC READ IOCTL CALL
  981.         POP     DS
  982.         JNC     IOCTL_OK
  983.         MOV     DX,OFFSET BADFIOCTL
  984.         MOV     BL,3            ;ERRORLEVEL3-ERROR DOS IOCTL
  985.         JMP     ERROR_OUT
  986. IOCTL_OK:
  987.         MOV     AH,3EH
  988.         INT     21H             ;CLOSE DEVICE HANDLE
  989.         LES     BX,IOCTL_PACKAD ;GET ADDR OF DEVICE HEADER
  990.         MOV     AX,ES
  991.         MOV     WORD PTR DEV_STRAT+2,AX ;GET ENTRIES FOR
  992.         MOV     WORD PTR DEV_INT+2,AX   ; STRATEGY
  993.         MOV     AX,ES:[BX].SDEVSTRAT    ; & INTERRUPT
  994.         MOV     WORD PTR DEV_STRAT,AX
  995.         MOV     AX,ES:[BX].SDEVINT
  996.         MOV     WORD PTR DEV_INT,AX
  997.         POP     BX
  998.         POP     ES                      ;GET EXISTING INT9
  999.         MOV     WORD PTR OLD_INT9,BX
  1000.         MOV     BX,ES
  1001.  
  1002.         MOV     WORD PTR OLD_INT9+2,BX
  1003.         MOV     IOCTLB.IOS_CMD,IOC_ADS_CMD  ;SET FOR DEVICE
  1004.         MOV     REQFLW.RQI_NBYTES,TYPE IOS  ; STATUS IOCTL
  1005.         CALL    IOCTL           ;DO IOCTL TO GET STATUS
  1006.         OR      AX,AX           ; OF DRIVE
  1007.         JZ      OKFIOCTL
  1008.         MOV     DX,OFFSET BADFIOCTL
  1009.         MOV     BL,4            ;ERRORLEVEL4 - ERR DEV IOCTL
  1010.         JMP     ERROR_OUT
  1011. OKFIOCTL:
  1012.         TEST    WORD PTR IOCTLB.IOS_STAT,IOS_AUDIO_PLAY
  1013.         JNZ     OKDEVCD                 ;CHK PLAY SUPPORTED
  1014.         MOV     DX,OFFSET INSUFDD
  1015.         MOV     BL,5         ;ERRORLEVEL5-PLAY UNSUPPORTED
  1016.         JMP     ERROR_OUT
  1017. OKDEVCD:
  1018.         CALL    TOC             ;READ THE TABLE OF CONTENTS
  1019.         MOV     IN_POPUP,1      ;DON'T ALLOW POPUP YET
  1020.         MOV     DX,OFFSET TRAP_KB
  1021.         PUSH    DS
  1022.         PUSH    CS
  1023.         POP     DS
  1024.         MOV     AX,2509H
  1025.         INT     21H             ;REPLACE INT9 ADDR VECTOR
  1026.         MOV     DX,OFFSET INSTALL_MSG
  1027.         MOV     AH,9
  1028.         INT     21H             ;SAY INSTALLED
  1029.         POP     DS
  1030.         MOV     ES,PSP
  1031.         MOV     AX,ES:[PSP_ENV]
  1032.         MOV     ES,AX           ;GET ENVIRONMENT ADDR
  1033.         MOV     AH,49H
  1034.         INT     21H             ;RELEASE ENVIRONMENT BLOCK
  1035.         MOV     DX,OFFSET KEEP_MEM
  1036.         ADD     DX,15
  1037.         MOV     CL,4
  1038.         SHR     DX,CL           ;CALC NUMBER OF PARAGRAPHS
  1039.         MOV     AX,CS           ; TO KEEP AFTER TSR
  1040.         ADD     DX,AX
  1041.         SUB     DX,PSP
  1042.         MOV     AX,3100H
  1043.         MOV     IN_POPUP,0      ;MAY NOW POPUP
  1044.         INT     21H             ;TERMINATE AND STAY RESIDENT
  1045. CDCNTL  ENDP
  1046. CODE    ENDS
  1047.  
  1048. STACKS  SEGMENT PARA STACK
  1049.         DW      256 DUP (?)
  1050. STACKS  ENDS
  1051.         END     CDCNTL
  1052.  
  1053. ; End of File 
  1054.  
  1055.