home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / x / volume21 / xmcd / part08 < prev    next >
Encoding:
Text File  |  1993-12-19  |  75.6 KB  |  3,507 lines

  1. Newsgroups: comp.sources.x
  2. From: ti@bazooka.amb.org (Ti Kan)
  3. Subject: v21i070:  xmcd - X11/Motif CD audio player, Part08/13
  4. Message-ID: <1993Dec19.193953.24519@sparky.sterling.com>
  5. X-Md4-Signature: 0290c5e6191ccc77c2581f31e885965c
  6. Sender: chris@sparky.sterling.com (Chris Olson)
  7. Organization: Sterling Software
  8. Date: Sun, 19 Dec 1993 19:39:53 GMT
  9. Approved: chris@sterling.com
  10.  
  11. Submitted-by: ti@bazooka.amb.org (Ti Kan)
  12. Posting-number: Volume 21, Issue 70
  13. Archive-name: xmcd/part08
  14. Environment: X11, OSF/Motif
  15.  
  16. #! /bin/sh
  17. # This is a shell archive.  Remove anything before this line, then unpack
  18. # it by saving it into a file and typing "sh file".  To overwrite existing
  19. # files, type "sh file -c".  You can also feed this as standard input via
  20. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  21. # will see the following message at the end:
  22. #        "End of archive 8 (of 13)."
  23. # Contents:  lib_demo.c lib_hita.c lib_hpux.c lib_nec.c lib_odt.c
  24. #   lib_pion.c lib_sim.c
  25. # Wrapped by ti@bazooka on Mon Nov  8 10:35:21 1993
  26. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  27. if test -f 'lib_demo.c' -a "${1}" != "-c" ; then 
  28.   echo shar: Will not clobber existing file \"'lib_demo.c'\"
  29. else
  30. echo shar: Extracting \"'lib_demo.c'\" \(6704 characters\)
  31. sed "s/^X//" >'lib_demo.c' <<'END_OF_FILE'
  32. X/*
  33. X *   xmcd - Motif(tm) CD Audio Player
  34. X *
  35. X *   Copyright (C) 1993  Ti Kan
  36. X *   E-mail: ti@amb.org
  37. X *
  38. X *   This program is free software; you can redistribute it and/or modify
  39. X *   it under the terms of the GNU General Public License as published by
  40. X *   the Free Software Foundation; either version 2 of the License, or
  41. X *   (at your option) any later version.
  42. X *
  43. X *   This program is distributed in the hope that it will be useful,
  44. X *   but WITHOUT ANY WARRANTY; without even the implied warranty of
  45. X *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  46. X *   GNU General Public License for more details.
  47. X *
  48. X *   You should have received a copy of the GNU General Public License
  49. X *   along with this program; if not, write to the Free Software
  50. X *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  51. X *
  52. X */
  53. X#ifndef LINT
  54. Xstatic char *_lib_demo_c_ident_ = "@(#)lib_demo.c    1.67 93/09/28";
  55. X#endif
  56. X
  57. X#include <Xm/Xm.h>
  58. X#include "xmcd.h"
  59. X#include "util.h"
  60. X#include "cdfunc.h"
  61. X#include "lib_scsipt.h"
  62. X
  63. X#ifdef SIMULATED_CDROM
  64. X
  65. X#ifndef OSI_VERS
  66. X#define OSI_VERS    "1.00"            /* Version */
  67. X#endif
  68. X
  69. X
  70. Xextern AppData        app_data;
  71. Xextern bool_t        notrom_error;
  72. X
  73. Xint            cdsim_sfd[2] = { -1, -1 },
  74. X            cdsim_rfd[2] = { -1, -1 };
  75. X#ifndef LINT
  76. Xbool_t            lib_demo = TRUE;
  77. X#endif
  78. X
  79. XSTATIC pid_t        cdsim_pid = -1;
  80. X
  81. X
  82. X/*
  83. X * pthru_send
  84. X *    Build SCSI CDB and sent command to the device.
  85. X *
  86. X * Args:
  87. X *    opcode - SCSI command opcode
  88. X *    addr - The "address" portion of the SCSI CDB
  89. X *    buf - Pointer to data buffer
  90. X *    size - Number of bytes to transfer
  91. X *    rsvd - The "reserved" portion of the SCSI CDB
  92. X *    length - The "length" portion of the SCSI CDB
  93. X *    param - The "param" portion of the SCSI CDB
  94. X *    control - The "control" portion of the SCSI CDB
  95. X *    rw - Data transfer direction flag (READ_OP or WRITE_OP)
  96. X *
  97. X * Return:
  98. X *    TRUE - command completed successfully
  99. X *    FALSE - command failed
  100. X */
  101. Xbool_t
  102. Xpthru_send(
  103. X    byte_t        opcode,
  104. X    word32_t    addr,
  105. X    byte_t        *buf,
  106. X    word32_t    size,
  107. X    byte_t        rsvd,
  108. X    word32_t    length,
  109. X    byte_t        param,
  110. X    byte_t        control,
  111. X    byte_t        rw
  112. X)
  113. X{
  114. X    simpkt_t    spkt,
  115. X            rpkt;
  116. X    static word32_t    pktid = 0;
  117. X
  118. X    if (cdsim_rfd[0] < 0 || cdsim_sfd[1] < 0 || notrom_error)
  119. X        return(FALSE);
  120. X
  121. X    memset(&spkt, (byte_t) 0, CDSIM_PKTSZ);
  122. X    memset(&rpkt, (byte_t) 0, CDSIM_PKTSZ);
  123. X
  124. X    /* Set up SCSI CDB */
  125. X    switch (opcode & 0xf0) {
  126. X    case 0xa0:
  127. X    case 0xe0:
  128. X        /* 12-byte commands */
  129. X        spkt.cdbsz = 12;
  130. X        spkt.cdb[0] = opcode;
  131. X        spkt.cdb[1] = param;
  132. X        spkt.cdb[2] = (addr >> 24) & 0xff;
  133. X        spkt.cdb[3] = (addr >> 16) & 0xff;
  134. X        spkt.cdb[4] = (addr >> 8) & 0xff;
  135. X        spkt.cdb[5] = (addr & 0xff);
  136. X        spkt.cdb[6] = (length >> 24) & 0xff;
  137. X        spkt.cdb[7] = (length >> 16) & 0xff;
  138. X        spkt.cdb[8] = (length >> 8) & 0xff;
  139. X        spkt.cdb[9] = length & 0xff;
  140. X        spkt.cdb[10] = rsvd;
  141. X        spkt.cdb[11] = control;
  142. X        break;
  143. X
  144. X    case 0xc0:
  145. X    case 0xd0:
  146. X    case 0x20:
  147. X    case 0x30:
  148. X    case 0x40:
  149. X        /* 10-byte commands */
  150. X        spkt.cdbsz = 10;
  151. X        spkt.cdb[0] = opcode;
  152. X        spkt.cdb[1] = param;
  153. X        spkt.cdb[2] = (addr >> 24) & 0xff;
  154. X        spkt.cdb[3] = (addr >> 16) & 0xff;
  155. X        spkt.cdb[4] = (addr >> 8) & 0xff;
  156. X        spkt.cdb[5] = addr & 0xff;
  157. X        spkt.cdb[6] = rsvd;
  158. X        spkt.cdb[7] = (length >> 8) & 0xff;
  159. X        spkt.cdb[8] = length & 0xff;
  160. X        spkt.cdb[9] = control;
  161. X        break;
  162. X
  163. X    case 0x00:
  164. X    case 0x10:
  165. X        /* 6-byte commands */
  166. X        spkt.cdbsz = 6;
  167. X        spkt.cdb[0] = opcode;
  168. X        spkt.cdb[1] = param;
  169. X        spkt.cdb[2] = (addr >> 8) & 0xff;
  170. X        spkt.cdb[3] = addr & 0xff;
  171. X        spkt.cdb[4] = length & 0xff;
  172. X        spkt.cdb[5] = control;
  173. X        break;
  174. X
  175. X    default:
  176. X        if (app_data.scsierr_msg)
  177. X            fprintf(stderr, "0x%02x: Unknown SCSI opcode\n",
  178. X                opcode);
  179. X        return(FALSE);
  180. X    }
  181. X
  182. X    spkt.len = (size > MAX_DATALEN) ? MAX_DATALEN : size;
  183. X    spkt.dir = rw;
  184. X    spkt.pktid = ++pktid;
  185. X
  186. X    /* Reset packet id if overflowing */
  187. X    if (pktid == 0xffff)
  188. X        pktid = 0;
  189. X
  190. X    /* Copy data from user buffer into packet */
  191. X    if (rw == WRITE_OP && buf != NULL && spkt.len != 0)
  192. X        memcpy(spkt.data, buf, spkt.len);
  193. X
  194. X    /* Send command packet */
  195. X    if (!cdsim_sendpkt("pthru", cdsim_sfd[1], &spkt))
  196. X        return(FALSE);
  197. X
  198. X    /* Get response packet */
  199. X    if (!cdsim_getpkt("pthru", cdsim_rfd[0], &rpkt))
  200. X        return(FALSE);
  201. X
  202. X    /* Sanity check */
  203. X    if (rpkt.pktid != spkt.pktid) {
  204. X        if (app_data.scsierr_msg)
  205. X            fprintf(stderr, "pthru: packet sequence error.\n");
  206. X
  207. X        return(FALSE);
  208. X    }
  209. X
  210. X    /* Check return status */
  211. X    if (rpkt.retcode != CDSIM_COMPOK) {
  212. X        if (app_data.scsierr_msg && spkt.cdb[0] != OP_S_TEST)
  213. X            fprintf(stderr,
  214. X                "pthru: cmd error (opcode=0x%x status=%d).\n",
  215. X                rpkt.cdb[0], rpkt.retcode);
  216. X
  217. X        return(FALSE);
  218. X    }
  219. X
  220. X    /* Copy data from packet into user buffer */
  221. X    if (rw == READ_OP && buf != NULL && rpkt.len != 0)
  222. X        memcpy(buf, rpkt.data, rpkt.len);
  223. X
  224. X    return(TRUE);
  225. X}
  226. X
  227. X
  228. X/*
  229. X * pthru_open
  230. X *    Open SCSI passthrough device
  231. X *
  232. X * Args:
  233. X *    path - device path name string
  234. X *
  235. X * Return:
  236. X *    TRUE - open successful
  237. X *    FALSE - open failed
  238. X */
  239. X/*ARGSUSED*/
  240. Xbool_t
  241. Xpthru_open(char *path)
  242. X{
  243. X    /* Hard code some capabilities parameters for the
  244. X     * simulated CD-ROM drive.  This overrides the
  245. X     * parameters from the device-specific config files.
  246. X     */
  247. X    app_data.device = "(none)";
  248. X    app_data.vendor_code = VENDOR_SCSI2;
  249. X    app_data.play10_supp = TRUE;
  250. X    app_data.play12_supp = TRUE;
  251. X    app_data.playmsf_supp = TRUE;
  252. X    app_data.playti_supp = TRUE;
  253. X    app_data.load_supp = TRUE;
  254. X    app_data.eject_supp = TRUE;
  255. X    app_data.mselvol_supp = FALSE;
  256. X    app_data.mselvol_dbd = FALSE;
  257. X    app_data.pause_supp = TRUE;
  258. X    app_data.caddylock_supp = TRUE;
  259. X
  260. X    /* Open pipe for IPC */
  261. X    if (pipe(cdsim_sfd) < 0 || pipe(cdsim_rfd) < 0) {
  262. X        cd_fatal_popup(app_data.str_fatal, "Cannot open pipe.");
  263. X        return(FALSE);
  264. X    }
  265. X
  266. X    /* Fork the CD simulator child */
  267. X    switch (cdsim_pid = fork()) {
  268. X    case -1:
  269. X        cd_fatal_popup(app_data.str_fatal, "Cannot fork.");
  270. X        return(FALSE);
  271. X
  272. X    case 0:
  273. X        /* Child: run CD simulator */
  274. X        cdsim_main();
  275. X        exit(0);
  276. X
  277. X    default:
  278. X        /* Parent: continue running the CD player */
  279. X#ifdef DEBUG
  280. X        fprintf(stderr, "pthru: forked cdsim child pid=%d\n",
  281. X            cdsim_pid);
  282. X#endif
  283. X        break;
  284. X    }
  285. X
  286. X    return(TRUE);
  287. X}
  288. X
  289. X
  290. X/*
  291. X * pthru_close
  292. X *    Close SCSI passthrough device
  293. X *
  294. X * Args:
  295. X *    Nothing.
  296. X *
  297. X * Return:
  298. X *    Nothing.
  299. X */
  300. Xvoid
  301. Xpthru_close(void)
  302. X{
  303. X    int    stat_val;
  304. X
  305. X    /* Close down pipes */
  306. X    close(cdsim_sfd[0]);
  307. X    close(cdsim_sfd[1]);
  308. X    close(cdsim_rfd[0]);
  309. X    close(cdsim_rfd[1]);
  310. X
  311. X    /* Shut down child */
  312. X    if (cdsim_pid > 0 && kill(cdsim_pid, 0) == 0)
  313. X        kill(cdsim_pid, SIGTERM);
  314. X
  315. X    /* Wait for child to exit */
  316. X    waitpid(cdsim_pid, &stat_val, 0);
  317. X}
  318. X
  319. X
  320. X/*
  321. X * pthru_vers
  322. X *    Return OS Interface Module version string
  323. X *
  324. X * Args:
  325. X *    Nothing.
  326. X *
  327. X * Return:
  328. X *    Module version text string.
  329. X */
  330. Xchar *
  331. Xpthru_vers(void)
  332. X{
  333. X    static char    vers[STR_BUF_SZ];
  334. X
  335. X    sprintf(vers, "OS Interface module v%s (Demo Dummy)\n", OSI_VERS);
  336. X    return(vers);
  337. X}
  338. X
  339. X
  340. X#else    /* !SIMULATED_CDROM */
  341. X
  342. X#ifndef LINT
  343. Xbool_t            lib_demo = FALSE;
  344. X#endif
  345. X
  346. X#endif    /* SIMULATED_CDROM */
  347. X
  348. END_OF_FILE
  349. if test 6704 -ne `wc -c <'lib_demo.c'`; then
  350.     echo shar: \"'lib_demo.c'\" unpacked with wrong size!
  351. fi
  352. # end of 'lib_demo.c'
  353. fi
  354. if test -f 'lib_hita.c' -a "${1}" != "-c" ; then 
  355.   echo shar: Will not clobber existing file \"'lib_hita.c'\"
  356. else
  357. echo shar: Extracting \"'lib_hita.c'\" \(11792 characters\)
  358. sed "s/^X//" >'lib_hita.c' <<'END_OF_FILE'
  359. X/*
  360. X *   xmcd - Motif(tm) CD Audio Player
  361. X *
  362. X *   Copyright (C) 1993  Ti Kan
  363. X *   E-mail: ti@amb.org
  364. X *
  365. X *   This program is free software; you can redistribute it and/or modify
  366. X *   it under the terms of the GNU General Public License as published by
  367. X *   the Free Software Foundation; either version 2 of the License, or
  368. X *   (at your option) any later version.
  369. X *
  370. X *   This program is distributed in the hope that it will be useful,
  371. X *   but WITHOUT ANY WARRANTY; without even the implied warranty of
  372. X *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  373. X *   GNU General Public License for more details.
  374. X *
  375. X *   You should have received a copy of the GNU General Public License
  376. X *   along with this program; if not, write to the Free Software
  377. X *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  378. X *
  379. X *   The name "Hitachi" is a trademark of Hitachi Corporation, and is
  380. X *   used here for identification purposes.  This software and its
  381. X *   author are not affiliated in any way with Hitachi.
  382. X *
  383. X */
  384. X#ifndef LINT
  385. Xstatic char *_lib_hita_c_ident_ = "@(#)lib_hita.c    1.36 93/09/28";
  386. X#endif
  387. X
  388. X#include <Xm/Xm.h>
  389. X#include "xmcd.h"
  390. X#include "util.h"
  391. X#include "cdfunc.h"
  392. X#include "lib_scsipt.h"
  393. X
  394. X#ifdef HITACHI
  395. X
  396. X#ifndef LINT
  397. Xbool_t            lib_hita = TRUE;
  398. X#endif
  399. X
  400. X
  401. XSTATIC bool_t        hita_paused = FALSE,        /* Currently paused */
  402. X            hita_playing = FALSE,        /* Currently playing */
  403. X            hita_audio_muted = FALSE;
  404. X                            /* Audio is muted */
  405. XSTATIC word32_t        hita_pause_addr = 0;        /* Pause addr */
  406. XSTATIC haudio_arg_t    hita_sav_end;            /* Save addr */
  407. X
  408. X
  409. X/*
  410. X * Internal functions
  411. X */
  412. X
  413. X/*
  414. X * hita_do_pause
  415. X *    Send a vendor-unique Pause command to the drive
  416. X *
  417. X * Args:
  418. X *    ret_addr - Pointer to a buffer where the paused address will be
  419. X *           written to.  If NULL, no pause address info will
  420. X *           returned.
  421. X *
  422. X * Return:
  423. X *    TRUE - success
  424. X *    FALSE - failure
  425. X */
  426. XSTATIC bool_t
  427. Xhita_do_pause(hmsf_t *ret_addr)
  428. X{
  429. X    hmsf_t    pause_addr;
  430. X    bool_t    ret;
  431. X
  432. X    if ((ret = pthru_send(OP_VH_PAUSE, 0,
  433. X                  (byte_t *) AD_VH_PAUSE(&pause_addr),
  434. X                  SZ_VH_PAUSE, 0, 0, 0, 0, READ_OP)) == TRUE) {
  435. X        if (ret_addr != NULL)
  436. X            *ret_addr = pause_addr;    /* structure copy */
  437. X    }
  438. X    return(ret);
  439. X}
  440. X
  441. X
  442. X/*
  443. X * Public functions
  444. X */
  445. X
  446. X/*
  447. X * hita_playaudio
  448. X *    Play audio function: send vendor-unique play audio command
  449. X *    to the drive.
  450. X *
  451. X * Args:
  452. X *    addr_fmt - Flags indicating which address formats are passed in
  453. X *    If ADDR_BLK, then:
  454. X *        start_addr - The logical block starting address
  455. X *        end_addr - The logical block ending address
  456. X *    If ADD_MSF, then:
  457. X *        start_msf - Pointer to the starting MSF address structure
  458. X *        end_msf - Pointer to the ending MSF address structure
  459. X *    If ADDR_TRKIDX, then:
  460. X *        trk - The starting track number
  461. X *        idx - The starting index number
  462. X *    If ADDR_OPTEND, then the ending address, if specified, can be
  463. X *    ignored if possible.
  464. X *
  465. X * Return:
  466. X *    TRUE - success
  467. X *    FALSE - failure
  468. X */
  469. X/*ARGSUSED*/
  470. Xbool_t
  471. Xhita_playaudio(
  472. X    byte_t        addr_fmt,
  473. X    word32_t    start_addr,
  474. X    word32_t    end_addr,
  475. X    msf_t        *start_msf,
  476. X    msf_t        *end_msf,
  477. X    byte_t        trk,
  478. X    byte_t        idx
  479. X)
  480. X{
  481. X    bool_t        ret = FALSE;
  482. X    msf_t        istart_msf,
  483. X            iend_msf;
  484. X    word32_t    addr1 = 0,
  485. X            addr2 = 0;
  486. X    haudio_arg_t    *a1,
  487. X            *a2;
  488. X    curstat_t    *s = curstat_addr();
  489. X
  490. X    a1 = (haudio_arg_t *) &addr1;
  491. X    a2 = (haudio_arg_t *) &addr2;
  492. X
  493. X    if (!ret && (addr_fmt & ADDR_BLK) && !(addr_fmt & ADDR_MSF)) {
  494. X        /* Convert block address to MSF format */
  495. X        blktomsf(
  496. X            start_addr,
  497. X            &istart_msf.min, &istart_msf.sec, &istart_msf.frame,
  498. X            MSF_OFFSET(s)
  499. X        );
  500. X
  501. X        blktomsf(
  502. X            end_addr,
  503. X            &iend_msf.min, &iend_msf.sec, &iend_msf.frame,
  504. X            MSF_OFFSET(s)
  505. X        );
  506. X
  507. X        /* Let the ADDR_MSF code handle the request */
  508. X        start_msf = &istart_msf;
  509. X        end_msf = &iend_msf;
  510. X        addr_fmt |= ADDR_MSF;
  511. X        ret = FALSE;
  512. X    }
  513. X
  514. X    if (!ret && (addr_fmt & ADDR_MSF)) {
  515. X        a1->addr_smin = (byte_t) start_msf->min;
  516. X        a1->addr_ssec = (byte_t) start_msf->sec;
  517. X        a1->addr_sframe = (byte_t) start_msf->frame;
  518. X
  519. X        a2->addr_emin = hita_sav_end.addr_emin = (byte_t) end_msf->min;
  520. X        a2->addr_esec = hita_sav_end.addr_esec = (byte_t) end_msf->sec;
  521. X        a2->addr_eframe = hita_sav_end.addr_eframe = (byte_t)
  522. X            end_msf->frame;
  523. X
  524. X        /* Send a pause command to cease any current audio playback,
  525. X         * then send the actual play audio command.
  526. X         */
  527. X        if ((ret = hita_do_pause(NULL)) == TRUE) {
  528. X            ret = pthru_send(
  529. X                OP_VH_AUDPLAY,
  530. X                addr1, NULL, 0, 0, addr2,
  531. X                (byte_t) (hita_audio_muted ? 0x7 : 0x1),
  532. X                0, READ_OP
  533. X            );
  534. X        }
  535. X    }
  536. X
  537. X    if (ret) {
  538. X        hita_paused = FALSE;
  539. X        hita_playing = TRUE;
  540. X    }
  541. X
  542. X    return(ret);
  543. X}
  544. X
  545. X
  546. X/*
  547. X * hita_pause_resume
  548. X *    Pause/resume function: send vendor-unique commands to implement
  549. X *    the pause and resume capability.
  550. X *
  551. X * Args:
  552. X *    resume - TRUE: resume, FALSE: pause
  553. X *
  554. X * Return:
  555. X *    TRUE - success
  556. X *    FALSE - failure
  557. X */
  558. Xbool_t
  559. Xhita_pause_resume(bool_t resume)
  560. X{
  561. X    bool_t        ret = FALSE;
  562. X    word32_t    addr1 = 0,
  563. X            addr2 = 0;
  564. X    haudio_arg_t    *a1,
  565. X            *a2;
  566. X    hmsf_t        *a;
  567. X
  568. X
  569. X    a1 = (haudio_arg_t *) &addr1;
  570. X    a2 = (haudio_arg_t *) &addr2;
  571. X    a = (hmsf_t *) &hita_pause_addr;
  572. X
  573. X        if (resume) {
  574. X        if (!hita_paused)
  575. X            return(TRUE);
  576. X
  577. X        a1->addr_smin = a->min;
  578. X        a1->addr_ssec = a->sec;
  579. X        a1->addr_sframe = a->frame;
  580. X        a2->addr_emin = hita_sav_end.addr_emin;
  581. X        a2->addr_esec = hita_sav_end.addr_esec;
  582. X        a2->addr_eframe = hita_sav_end.addr_eframe;
  583. X
  584. X        ret = pthru_send(
  585. X            OP_VH_AUDPLAY,
  586. X            addr1, NULL, 0, 0, addr2,
  587. X            (byte_t) (hita_audio_muted ? 0x7 : 0x1),
  588. X            0, READ_OP
  589. X        );
  590. X        }
  591. X        else {
  592. X        if (hita_paused)
  593. X            return(TRUE);
  594. X
  595. X        ret = hita_do_pause(a);
  596. X    }
  597. X
  598. X    if (ret) {
  599. X        hita_paused = !resume;
  600. X        hita_playing = !hita_paused;
  601. X    }
  602. X
  603. X    return(ret);
  604. X}
  605. X
  606. X
  607. X/*
  608. X * hita_start_stop
  609. X *    Start/stop function: When playing audio, the Hitachi drive must
  610. X *    first be paused before sending a Start/Stop Unit command to
  611. X *    stop it.  This routine performs the pause.
  612. X *
  613. X * Args:
  614. X *    start - TRUE: start unit, FALSE: stop unit
  615. X *    loej - TRUE: load/eject caddy, FALSE: do not load/eject (not used)
  616. X *
  617. X * Return:
  618. X *    TRUE - success
  619. X *    FALSE - failure
  620. X */
  621. X/*ARGSUSED*/
  622. Xbool_t
  623. Xhita_start_stop(bool_t start, bool_t loej)
  624. X{
  625. X    /* If audio playback is in progress, pause the playback.
  626. X     * Then, return to caller (do_start_stop() in lib_scsipt.c)
  627. X     * and issue a start/stop unit command from there.
  628. X     */
  629. X    if (!start && hita_playing) {
  630. X        hita_playing = FALSE;
  631. X
  632. X        return(hita_do_pause(NULL));
  633. X    }
  634. X
  635. X    hita_paused = FALSE;
  636. X    return(TRUE);
  637. X}
  638. X
  639. X
  640. X/*
  641. X * hita_get_playstatus
  642. X *    Send vendor-unique command to obtain current audio playback
  643. X *    status.
  644. X *
  645. X * Args:
  646. X *    s - Pointer to the curstat_t structure
  647. X *    audio_status - Address where a current status code (SCSI-2
  648. X *               style) is to be returned.
  649. X *
  650. X * Return:
  651. X *    TRUE - success
  652. X *    FALSE - failure
  653. X */
  654. Xbool_t
  655. Xhita_get_playstatus(curstat_t *s, byte_t *audio_status)
  656. X{
  657. X    int        trkno,
  658. X            idxno;
  659. X    byte_t        buf[SZ_VH_RDSTAT];
  660. X    haudstat_t    *d;
  661. X
  662. X
  663. X    memset(buf, (byte_t) 0, sizeof(buf));
  664. X
  665. X    if (!pthru_send(OP_VH_RDSTAT, 0, (byte_t *) AD_VH_RDSTAT(buf),
  666. X            SZ_VH_RDSTAT, 0, 0, 0, 0, READ_OP))
  667. X        return(FALSE);
  668. X
  669. X    d = (haudstat_t *)(void *) buf;
  670. X
  671. X    trkno = (word32_t) d->trkno;
  672. X    if (s->cur_trk != trkno) {
  673. X        s->cur_trk = trkno;
  674. X        dpy_track(s);
  675. X    }
  676. X    idxno = 1;    /* Fudge */
  677. X    if (s->cur_idx != idxno) {
  678. X        s->cur_idx = idxno;
  679. X        dpy_index(s);
  680. X    }
  681. X
  682. X    s->cur_tot_min = (byte_t) d->abs_addr.min;
  683. X    s->cur_tot_sec = (byte_t) d->abs_addr.sec;
  684. X    s->cur_tot_frame = (byte_t) d->abs_addr.frame;
  685. X    s->cur_trk_min = (byte_t) d->rel_addr.min;
  686. X    s->cur_trk_sec = (byte_t) d->rel_addr.sec;
  687. X    s->cur_trk_frame = (byte_t) d->rel_addr.frame;
  688. X    msftoblk(
  689. X        s->cur_tot_min, s->cur_tot_sec, s->cur_tot_frame,
  690. X        &s->cur_tot_addr, MSF_OFFSET(s)
  691. X    );
  692. X    msftoblk(
  693. X        s->cur_trk_min, s->cur_trk_sec, s->cur_trk_frame,
  694. X        &s->cur_trk_addr, 0
  695. X    );
  696. X
  697. X    /* Make up SCSI-2 style audio status */
  698. X    if (hita_paused)
  699. X        *audio_status = AUDIO_PAUSED;
  700. X    else if (d->playing)
  701. X        *audio_status = AUDIO_PLAYING;
  702. X    else {
  703. X        *audio_status = AUDIO_COMPLETED;
  704. X        hita_playing = FALSE;
  705. X    }
  706. X
  707. X    return(TRUE);
  708. X}
  709. X
  710. X
  711. X/*
  712. X * hita_get_toc
  713. X *    Send vendor-unique command to obtain the disc table-of-contents
  714. X *
  715. X * Args:
  716. X *    s - Pointer to the curstat_t structure, which contains the TOC
  717. X *        table to be updated.
  718. X *
  719. X * Return:
  720. X *    TRUE - success
  721. X *    FALSE - failure
  722. X */
  723. Xbool_t
  724. Xhita_get_toc(curstat_t *s)
  725. X{
  726. X    int        i,
  727. X            j,
  728. X            xfer_len;
  729. X    byte_t        buf[sizeof(hdiscinfo_t)];
  730. X    hdiscinfo_t    *p;
  731. X    hmsf_t        *a;
  732. X
  733. X
  734. X    if (hita_playing)
  735. X        return(FALSE);    /* Drive is busy */
  736. X
  737. X    memset(buf, (byte_t) 0, sizeof(buf));
  738. X
  739. X    /* Read the TOC header first */
  740. X    if (!pthru_send(OP_VH_RDINFO, 0, (byte_t *) AD_VH_RDINFO(buf),
  741. X            SZ_VH_TOCHDR, SZ_VH_TOCHDR & 0xff,
  742. X            SZ_VH_TOCHDR >> 8, 0, 0, READ_OP))
  743. X        return(FALSE);
  744. X
  745. X    p = (hdiscinfo_t *)(void *) buf;
  746. X
  747. X    s->first_trk = (byte_t) p->first_trk;
  748. X    s->last_trk = (byte_t) p->last_trk;
  749. X
  750. X    xfer_len = SZ_VH_TOCHDR +
  751. X           ((int) (p->last_trk - p->first_trk + 2) * SZ_VH_TOCENT);
  752. X
  753. X    if (xfer_len > SZ_VH_RDINFO)
  754. X        xfer_len = SZ_VH_RDINFO;
  755. X
  756. X    /* Read the appropriate number of bytes of the entire TOC */
  757. X    if (!pthru_send(OP_VH_RDINFO, 0, (byte_t *) AD_VH_RDINFO(buf),
  758. X            xfer_len, (byte_t) (xfer_len & 0xff), xfer_len >> 8,
  759. X            0, 0, READ_OP))
  760. X        return(FALSE);
  761. X
  762. X    /* Get the starting position of each track */
  763. X    for (i = 0, j = (int) s->first_trk; j <= (int) s->last_trk; i++, j++) {
  764. X        a = (hmsf_t *)(void *) &p->msfdata[(i+1) * 3];
  765. X        s->trkinfo[i].trkno = j;
  766. X        s->trkinfo[i].min = (byte_t) a->min;
  767. X        s->trkinfo[i].sec = (byte_t) a->sec;
  768. X        s->trkinfo[i].frame = (byte_t) a->frame;
  769. X        msftoblk(
  770. X            s->trkinfo[i].min,
  771. X            s->trkinfo[i].sec,
  772. X            s->trkinfo[i].frame,
  773. X            &s->trkinfo[i].addr,
  774. X            MSF_OFFSET(s)
  775. X        );
  776. X        s->trkinfo[i].type = (a->data == 0) ? TYP_AUDIO : TYP_DATA;
  777. X    }
  778. X    s->tot_trks = (byte_t) i;
  779. X
  780. X    /* Get the lead-out track position */
  781. X    a = (hmsf_t *)(void *) &p->msfdata[0];
  782. X    s->trkinfo[i].trkno = LEAD_OUT_TRACK;
  783. X    s->tot_min = s->trkinfo[i].min = (byte_t) a->min;
  784. X    s->tot_sec = s->trkinfo[i].sec = (byte_t) a->sec;
  785. X    s->tot_frame = s->trkinfo[i].frame = (byte_t) a->frame;
  786. X    msftoblk(
  787. X        s->trkinfo[i].min,
  788. X        s->trkinfo[i].sec,
  789. X        s->trkinfo[i].frame,
  790. X        &s->trkinfo[i].addr,
  791. X        MSF_OFFSET(s)
  792. X    );
  793. X    s->tot_addr = s->trkinfo[i].addr;
  794. X
  795. X    return(TRUE);
  796. X}
  797. X
  798. X
  799. X/*
  800. X * hita_mute
  801. X *    Send vendor-unique command to mute/unmute the audio
  802. X *
  803. X * Args:
  804. X *    mute - TRUE: mute audio, FALSE: un-mute audio
  805. X *
  806. X * Return:
  807. X *    TRUE - success
  808. X *    FALSE - failure
  809. X */
  810. Xbool_t
  811. Xhita_mute(bool_t mute)
  812. X{
  813. X    word32_t    addr1 = 0,
  814. X            addr2 = 0;
  815. X    haudio_arg_t    *a1,
  816. X            *a2;
  817. X    curstat_t    *s = curstat_addr();
  818. X
  819. X
  820. X    if (mute == hita_audio_muted)
  821. X        return(TRUE);
  822. X
  823. X    a1 = (haudio_arg_t *) &addr1;
  824. X    a2 = (haudio_arg_t *) &addr2;
  825. X
  826. X    if (hita_playing) {
  827. X        /* Pause the playback first */
  828. X            if (!hita_do_pause(NULL))
  829. X            return(FALSE);
  830. X
  831. X        a1->addr_smin = (byte_t) s->cur_tot_min;
  832. X        a1->addr_ssec = (byte_t) s->cur_tot_sec;
  833. X        a1->addr_sframe = (byte_t) s->cur_tot_frame;
  834. X        a2->addr_emin = hita_sav_end.addr_emin;
  835. X        a2->addr_esec = hita_sav_end.addr_esec;
  836. X        a2->addr_eframe = hita_sav_end.addr_eframe;
  837. X
  838. X        if (!pthru_send(OP_VH_AUDPLAY, addr1, NULL, 0, 0, addr2,
  839. X                (byte_t) (mute ? 0x7 : 0x1), 0, READ_OP))
  840. X            return(FALSE);
  841. X    }
  842. X
  843. X    hita_audio_muted = mute;
  844. X
  845. X    return(TRUE);
  846. X}
  847. X
  848. X
  849. X/*
  850. X * hita_eject
  851. X *    Send vendor-unique command to eject the caddy
  852. X *
  853. X * Args:
  854. X *    Nothing.
  855. X *
  856. X * Return:
  857. X *    TRUE - success
  858. X *    FALSE - failure
  859. X */
  860. Xbool_t
  861. Xhita_eject(void)
  862. X{
  863. X    /* If audio playback is in progress, pause the playback first */
  864. X    if (hita_playing && !hita_do_pause(NULL))
  865. X        return(FALSE);
  866. X
  867. X    hita_playing = hita_paused = FALSE;
  868. X
  869. X    /* Eject the caddy */
  870. X    return(pthru_send(OP_VH_EJECT, 0, NULL, 0, 0x1, 0, 0, 0, READ_OP));
  871. X}
  872. X
  873. X
  874. X/*
  875. X * hita_init
  876. X *    Initialize the vendor-unique support module
  877. X *
  878. X * Args:
  879. X *    Nothing.
  880. X *
  881. X * Return:
  882. X *    Nothing.
  883. X */
  884. Xvoid
  885. Xhita_init(void)
  886. X{
  887. X    /* Do nothing */
  888. X}
  889. X
  890. X
  891. X/*
  892. X * hita_halt
  893. X *    Shut down the vendor-unique support module
  894. X *
  895. X * Args:
  896. X *    Nothing.
  897. X *
  898. X * Return:
  899. X *    Nothing.
  900. X */
  901. Xvoid
  902. Xhita_halt(void)
  903. X{
  904. X    /* Do nothing */
  905. X}
  906. X
  907. X
  908. X#else    /* !HITACHI */
  909. X
  910. X#ifndef LINT
  911. Xbool_t                lib_hita = FALSE;
  912. X#endif
  913. X
  914. X#endif    /* HITACHI */
  915. X
  916. END_OF_FILE
  917. if test 11792 -ne `wc -c <'lib_hita.c'`; then
  918.     echo shar: \"'lib_hita.c'\" unpacked with wrong size!
  919. fi
  920. # end of 'lib_hita.c'
  921. fi
  922. if test -f 'lib_hpux.c' -a "${1}" != "-c" ; then 
  923.   echo shar: Will not clobber existing file \"'lib_hpux.c'\"
  924. else
  925. echo shar: Extracting \"'lib_hpux.c'\" \(6448 characters\)
  926. sed "s/^X//" >'lib_hpux.c' <<'END_OF_FILE'
  927. X/*
  928. X *   xmcd - Motif(tm) CD Audio Player
  929. X *
  930. X *   Copyright (C) 1993  Ti Kan
  931. X *   E-mail: ti@amb.org
  932. X *
  933. X *   This program is free software; you can redistribute it and/or modify
  934. X *   it under the terms of the GNU General Public License as published by
  935. X *   the Free Software Foundation; either version 2 of the License, or
  936. X *   (at your option) any later version.
  937. X *
  938. X *   This program is distributed in the hope that it will be useful,
  939. X *   but WITHOUT ANY WARRANTY; without even the implied warranty of
  940. X *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  941. X *   GNU General Public License for more details.
  942. X *
  943. X *   You should have received a copy of the GNU General Public License
  944. X *   along with this program; if not, write to the Free Software
  945. X *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  946. X *
  947. X *   This software module contains code that interfaces xmcd to
  948. X *   the HP-UX Release 9.0 operating system.  The name "HP" and "hpux"
  949. X *   are used here for identification purposes.  This software and
  950. X *   its author are not affiliated with the Hewlett-Packard Company.
  951. X */
  952. X#ifndef LINT
  953. Xstatic char *_lib_hpux_c_ident_ = "@(#)lib_hpux.c    1.8 93/09/28";
  954. X#endif
  955. X
  956. X#include <Xm/Xm.h>
  957. X#include "xmcd.h"
  958. X#include "util.h"
  959. X#include "cdfunc.h"
  960. X#include "lib_scsipt.h"
  961. X
  962. X#if defined(hpux) && !defined(SIMULATED_CDROM)
  963. X
  964. X#ifndef OSI_VERS
  965. X#define OSI_VERS    "1.0"        /* Version */
  966. X#endif
  967. X
  968. X
  969. Xextern AppData        app_data;
  970. Xextern bool_t        notrom_error;
  971. X
  972. X#ifndef LINT
  973. Xbool_t            lib_hpux = TRUE;
  974. X#endif
  975. X
  976. XSTATIC int        fd = -1;    /* Passthrough device file desc */
  977. X
  978. X
  979. X/*
  980. X * pthru_send
  981. X *    Build SCSI CDB and sent command to the device.
  982. X *
  983. X * Args:
  984. X *    opcode - SCSI command opcode
  985. X *    addr - The "address" portion of the SCSI CDB
  986. X *    buf - Pointer to data buffer
  987. X *    size - Number of bytes to transfer
  988. X *    rsvd - The "reserved" portion of the SCSI CDB
  989. X *    length - The "length" portion of the SCSI CDB
  990. X *    param - The "param" portion of the SCSI CDB
  991. X *    control - The "control" portion of the SCSI CDB
  992. X *    rw - Data transfer direction flag (READ_OP or WRITE_OP)
  993. X *
  994. X * Return:
  995. X *    TRUE - command completed successfully
  996. X *    FALSE - command failed
  997. X */
  998. Xbool_t
  999. Xpthru_send(
  1000. X    byte_t        opcode,
  1001. X    word32_t    addr,
  1002. X    byte_t        *buf,
  1003. X    word32_t    size,
  1004. X    byte_t        rsvd,
  1005. X    word32_t    length,
  1006. X    byte_t        param,
  1007. X    byte_t        control,
  1008. X    byte_t        rw
  1009. X)
  1010. X{
  1011. X    struct sctl_io    sctl;
  1012. X
  1013. X    
  1014. X    if (fd < 0 || notrom_error)
  1015. X        return(FALSE);
  1016. X
  1017. X    memset(&sctl, (byte_t) 0, sizeof(sctl));
  1018. X
  1019. X    /* set up SCSI CDB */
  1020. X    switch (opcode & 0xf0) {
  1021. X    case 0xa0:
  1022. X    case 0xe0:
  1023. X        /* 12-byte commands */
  1024. X        sctl.cdb[0] = opcode;
  1025. X        sctl.cdb[1] = param;
  1026. X        sctl.cdb[2] = (addr >> 24) & 0xff;
  1027. X        sctl.cdb[3] = (addr >> 16) & 0xff;
  1028. X        sctl.cdb[4] = (addr >> 8) & 0xff;
  1029. X        sctl.cdb[5] = (addr & 0xff);
  1030. X        sctl.cdb[6] = (length >> 24) & 0xff;
  1031. X        sctl.cdb[7] = (length >> 16) & 0xff;
  1032. X        sctl.cdb[8] = (length >> 8) & 0xff;
  1033. X        sctl.cdb[9] = length & 0xff;
  1034. X        sctl.cdb[10] = rsvd;
  1035. X        sctl.cdb[11] = control;
  1036. X
  1037. X        sctl.cdb_length = 12;
  1038. X        break;
  1039. X
  1040. X    case 0xc0:
  1041. X    case 0xd0:
  1042. X    case 0x20:
  1043. X    case 0x30:
  1044. X    case 0x40:
  1045. X        /* 10-byte commands */
  1046. X        sctl.cdb[0] = opcode;
  1047. X        sctl.cdb[1] = param;
  1048. X        sctl.cdb[2] = (addr >> 24) & 0xff;
  1049. X        sctl.cdb[3] = (addr >> 16) & 0xff;
  1050. X        sctl.cdb[4] = (addr >> 8) & 0xff;
  1051. X        sctl.cdb[5] = addr & 0xff;
  1052. X        sctl.cdb[6] = rsvd;
  1053. X        sctl.cdb[7] = (length >> 8) & 0xff;
  1054. X        sctl.cdb[8] = length & 0xff;
  1055. X        sctl.cdb[9] = control;
  1056. X
  1057. X        sctl.cdb_length = 10;
  1058. X        break;
  1059. X
  1060. X    case 0x00:
  1061. X    case 0x10:
  1062. X        /* 6-byte commands */
  1063. X        sctl.cdb[0] = opcode;
  1064. X        sctl.cdb[1] = param;
  1065. X        sctl.cdb[2] = (addr >> 8) & 0xff;
  1066. X        sctl.cdb[3] = addr & 0xff;
  1067. X        sctl.cdb[4] = length & 0xff;
  1068. X        sctl.cdb[5] = control;
  1069. X
  1070. X        sctl.cdb_length = 6;
  1071. X        break;
  1072. X
  1073. X    default:
  1074. X        if (app_data.scsierr_msg)
  1075. X            fprintf(stderr, "0x%02x: Unknown SCSI opcode\n",
  1076. X                opcode);
  1077. X        return(FALSE);
  1078. X    }
  1079. X
  1080. X#ifdef DEBUG
  1081. X    {
  1082. X        byte_t    *p = (byte_t *) &sctl.cdb[0];
  1083. X        int    i;
  1084. X
  1085. X        fprintf(stderr, "\nSCSI CDB bytes:");
  1086. X        for (i = 0; i < sctl.cdb_length; i++, p++)
  1087. X            fprintf(stderr, " %02x", i, *p);
  1088. X        fprintf(stderr, "\n");
  1089. X    }
  1090. X#endif
  1091. X
  1092. X    /* set up sctl_io */
  1093. X    sctl.data = buf;
  1094. X    sctl.data_length = (unsigned) size;
  1095. X    if (rw == READ_OP && size > 0)
  1096. X        sctl.flags = SCTL_READ;
  1097. X    else
  1098. X        sctl.flags = 0;
  1099. X
  1100. X    sctl.max_msecs = 10000;    /* Allow 10 seconds for command */
  1101. X
  1102. X    /* Send the command down via the "pass-through" interface */
  1103. X    if (ioctl(fd, SIOC_IO, &sctl) < 0) {
  1104. X        perror("SIOC_IO ioctl failed");
  1105. X        return(FALSE);
  1106. X    }
  1107. X
  1108. X    if (sctl.cdb_status != S_GOOD) {
  1109. X        if (opcode != OP_S_TEST && app_data.scsierr_msg) {
  1110. X            fprintf(stderr, "%s: %s %s:\n%s=0x%x %s=0x%x %s=0x%x",
  1111. X                PROGNAME,
  1112. X                "SCSI command fault on",
  1113. X                app_data.device,
  1114. X                "Opcode",
  1115. X                opcode,
  1116. X                "Cdb_status",
  1117. X                sctl.cdb_status,
  1118. X                "Sense_status",
  1119. X                sctl.sense_status);
  1120. X
  1121. X            if (sctl.sense_status == S_GOOD && sctl.sense_xfer > 2)
  1122. X                fprintf(stderr,
  1123. X                    " Key=0x%x Code=0x%x Qual=0x%x\n",
  1124. X                    sctl.sense[2] & 0x0f,
  1125. X                    sctl.sense[12],
  1126. X                    sctl.sense[13]);
  1127. X            else
  1128. X                fprintf(stderr, "\n");
  1129. X        }
  1130. X
  1131. X        return(FALSE);
  1132. X    }
  1133. X
  1134. X    return(TRUE);
  1135. X}
  1136. X
  1137. X
  1138. X/*
  1139. X * pthru_open
  1140. X *    Open SCSI passthrough device
  1141. X *
  1142. X * Args:
  1143. X *    path - device path name string
  1144. X *
  1145. X * Return:
  1146. X *    TRUE - open successful
  1147. X *    FALSE - open failed
  1148. X */
  1149. Xbool_t
  1150. Xpthru_open(char *path)
  1151. X{
  1152. X    struct stat    stbuf;
  1153. X    char        errstr[STR_BUF_SZ];
  1154. X
  1155. X    /* Check for validity of device node */
  1156. X    if (stat(path, &stbuf) < 0) {
  1157. X        sprintf(errstr, app_data.str_staterr, path);
  1158. X        cd_fatal_popup(app_data.str_fatal, errstr);
  1159. X        return(FALSE);
  1160. X    }
  1161. X    if ((stbuf.st_mode & S_IFMT) != S_IFCHR) {
  1162. X        sprintf(errstr, app_data.str_noderr, path);
  1163. X        cd_fatal_popup(app_data.str_fatal, errstr);
  1164. X        return(FALSE);
  1165. X    }
  1166. X
  1167. X    /* Check for another copy of xmcd running on the same
  1168. X     * CD-ROM device.
  1169. X     */
  1170. X    if (!cd_devlock(path))
  1171. X        return(FALSE);
  1172. X
  1173. X    if ((fd = open(path, O_RDONLY)) < 0)
  1174. X        return(FALSE);
  1175. X
  1176. X    /* Obtain exclusive open */
  1177. X    if (ioctl(fd, SIOC_EXCLUSIVE, 1) < 0) {
  1178. X        close(fd);
  1179. X        fd = -1;
  1180. X        return(FALSE);
  1181. X    }
  1182. X
  1183. X    return(TRUE);
  1184. X}
  1185. X
  1186. X
  1187. X/*
  1188. X * pthru_close
  1189. X *    Close SCSI passthrough device
  1190. X *
  1191. X * Args:
  1192. X *    Nothing.
  1193. X *
  1194. X * Return:
  1195. X *    Nothing.
  1196. X */
  1197. Xvoid
  1198. Xpthru_close(void)
  1199. X{
  1200. X    if (fd >= 0) {
  1201. X        /* Relinquish exclusive open */
  1202. X        ioctl(fd, SIOC_EXCLUSIVE, 0);
  1203. X
  1204. X        close(fd);
  1205. X        fd = -1;
  1206. X    }
  1207. X}
  1208. X
  1209. X
  1210. X/*
  1211. X * pthru_vers
  1212. X *    Return OS Interface Module version string
  1213. X *
  1214. X * Args:
  1215. X *    Nothing.
  1216. X *
  1217. X * Return:
  1218. X *    Module version text string.
  1219. X */
  1220. Xchar *
  1221. Xpthru_vers(void)
  1222. X{
  1223. X    static char    vers[STR_BUF_SZ];
  1224. X
  1225. X    sprintf(vers, "OS Interface module v%s (for HP-UX)\n", OSI_VERS);
  1226. X    return(vers);
  1227. X}
  1228. X
  1229. X
  1230. X#else    /* !hpux || !SIMULATED_CDROM */
  1231. X
  1232. X#ifndef LINT
  1233. Xbool_t            lib_hpux = FALSE;
  1234. X#endif
  1235. X
  1236. X#endif    /* hpux SIMULATED_CDROM */
  1237. X
  1238. END_OF_FILE
  1239. if test 6448 -ne `wc -c <'lib_hpux.c'`; then
  1240.     echo shar: \"'lib_hpux.c'\" unpacked with wrong size!
  1241. fi
  1242. # end of 'lib_hpux.c'
  1243. fi
  1244. if test -f 'lib_nec.c' -a "${1}" != "-c" ; then 
  1245.   echo shar: Will not clobber existing file \"'lib_nec.c'\"
  1246. else
  1247. echo shar: Extracting \"'lib_nec.c'\" \(9492 characters\)
  1248. sed "s/^X//" >'lib_nec.c' <<'END_OF_FILE'
  1249. X/*
  1250. X *   xmcd - Motif(tm) CD Audio Player
  1251. X *
  1252. X *   Copyright (C) 1993  Ti Kan
  1253. X *   E-mail: ti@amb.org
  1254. X *
  1255. X *   This program is free software; you can redistribute it and/or modify
  1256. X *   it under the terms of the GNU General Public License as published by
  1257. X *   the Free Software Foundation; either version 2 of the License, or
  1258. X *   (at your option) any later version.
  1259. X *
  1260. X *   This program is distributed in the hope that it will be useful,
  1261. X *   but WITHOUT ANY WARRANTY; without even the implied warranty of
  1262. X *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  1263. X *   GNU General Public License for more details.
  1264. X *
  1265. X *   You should have received a copy of the GNU General Public License
  1266. X *   along with this program; if not, write to the Free Software
  1267. X *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  1268. X *
  1269. X *   The name "NEC" is a trademark of NEC Corporation, and is
  1270. X *   used here for identification purposes.  This software and its
  1271. X *   author are not affiliated in any way with NEC.
  1272. X *
  1273. X */
  1274. X#ifndef LINT
  1275. Xstatic char *_lib_nec_c_ident_ = "@(#)lib_nec.c    1.30 93/09/28";
  1276. X#endif
  1277. X
  1278. X#include <Xm/Xm.h>
  1279. X#include "xmcd.h"
  1280. X#include "util.h"
  1281. X#include "cdfunc.h"
  1282. X#include "lib_scsipt.h"
  1283. X
  1284. X#ifdef NEC
  1285. X
  1286. X
  1287. X#ifndef LINT
  1288. Xbool_t        lib_nec = TRUE;
  1289. X#endif
  1290. X
  1291. XSTATIC bool_t    nec_audio_muted = FALSE;    /* Is audio muted? */
  1292. X
  1293. X
  1294. X/*
  1295. X * nec_playaudio
  1296. X *    Play audio function: send vendor-unique play audio command
  1297. X *    to the drive.
  1298. X *
  1299. X * Args:
  1300. X *    addr_fmt - Flags indicating which address formats are passed in
  1301. X *    If ADDR_BLK, then:
  1302. X *        start_addr - The logical block starting address
  1303. X *        end_addr - The logical block ending address
  1304. X *    If ADD_MSF, then:
  1305. X *        start_msf - Pointer to the starting MSF address structure
  1306. X *        end_msf - Pointer to the ending MSF address structure
  1307. X *    If ADDR_TRKIDX, then:
  1308. X *        trk - The starting track number
  1309. X *        idx - The starting index number
  1310. X *    If ADDR_OPTEND, then the ending address, if specified, can be
  1311. X *    ignored if possible.
  1312. X *
  1313. X * Return:
  1314. X *    TRUE - success
  1315. X *    FALSE - failure
  1316. X */
  1317. X/*ARGSUSED*/
  1318. Xbool_t
  1319. Xnec_playaudio(
  1320. X    byte_t        addr_fmt,
  1321. X    word32_t    start_addr,
  1322. X    word32_t    end_addr,
  1323. X    msf_t        *start_msf,
  1324. X    msf_t        *end_msf,
  1325. X    byte_t        trk,
  1326. X    byte_t        idx
  1327. X)
  1328. X{
  1329. X    bool_t        ret = FALSE;
  1330. X    word32_t    addr = 0;
  1331. X    naudio_arg_t    *p;
  1332. X
  1333. X    p = (naudio_arg_t *) &addr;
  1334. X
  1335. X    if (!ret && addr_fmt & ADDR_MSF) {
  1336. X        if (addr_fmt & ADDR_OPTEND) {
  1337. X            /* Position laser head at desired location
  1338. X             * and start play.
  1339. X             */
  1340. X            p->addr_min = (byte_t) ltobcd(start_msf->min);
  1341. X            p->addr_sec = (byte_t) ltobcd(start_msf->sec);
  1342. X            p->addr_frame = (byte_t) ltobcd(start_msf->frame);
  1343. X
  1344. X            ret = pthru_send(
  1345. X                OP_VN_AUDSRCH,
  1346. X                addr, NULL, 0, 0, 0,
  1347. X                0x1, 0x1 << 6, READ_OP
  1348. X            );
  1349. X        }
  1350. X        else {
  1351. X            /* Position laser head at desired location */
  1352. X            p->addr_min = (byte_t) ltobcd(start_msf->min);
  1353. X            p->addr_sec = (byte_t) ltobcd(start_msf->sec);
  1354. X            p->addr_frame = (byte_t) ltobcd(start_msf->frame);
  1355. X
  1356. X            if (!pthru_send(OP_VN_AUDSRCH,
  1357. X                    addr, NULL, 0, 0, 0,
  1358. X                    0x0, 0x1 << 6, READ_OP))
  1359. X                return(FALSE);
  1360. X
  1361. X            /* Specify end location, muting, and start play */
  1362. X            p->addr_min = (byte_t) ltobcd(end_msf->min);
  1363. X            p->addr_sec = (byte_t) ltobcd(end_msf->sec);
  1364. X            p->addr_frame = (byte_t) ltobcd(end_msf->frame);
  1365. X
  1366. X            ret = pthru_send(
  1367. X                OP_VN_AUDPLAY,
  1368. X                addr, NULL, 0, 0, 0,
  1369. X                (byte_t) (nec_audio_muted ? 0x0 : 0x3),
  1370. X                0x1 << 6, READ_OP
  1371. X            );
  1372. X        }
  1373. X    }
  1374. X
  1375. X    if (!ret && addr_fmt & ADDR_BLK) {
  1376. X        if (addr_fmt & ADDR_OPTEND) {
  1377. X            /* Position laser head at desired location
  1378. X             * and start play.
  1379. X             */
  1380. X            p->addr_logical = start_addr;
  1381. X
  1382. X            ret = pthru_send(
  1383. X                OP_VN_AUDSRCH,
  1384. X                addr, NULL, 0, 0, 0,
  1385. X                0x1, 0x0, READ_OP
  1386. X            );
  1387. X        }
  1388. X        else {
  1389. X            /* Position laser head at desired location */
  1390. X            p->addr_logical = start_addr;
  1391. X
  1392. X            if (!pthru_send(OP_VN_AUDSRCH,
  1393. X                    addr, NULL, 0, 0, 0,
  1394. X                    0x0, 0x0, READ_OP))
  1395. X                return(FALSE);
  1396. X
  1397. X            /* Specify end location, muting, and start play */
  1398. X            p->addr_logical = end_addr;
  1399. X
  1400. X            ret = pthru_send(
  1401. X                OP_VN_AUDPLAY,
  1402. X                addr, NULL, 0, 0, 0,
  1403. X                (byte_t) (nec_audio_muted ? 0x0 : 0x3),
  1404. X                0x0, READ_OP
  1405. X            );
  1406. X        }
  1407. X    }
  1408. X
  1409. X    return(ret);
  1410. X}
  1411. X
  1412. X
  1413. X/*
  1414. X * nec_pause_resume
  1415. X *    Pause/resume function: send vendor-unique commands to implement
  1416. X *    the pause and resume capability.
  1417. X *
  1418. X * Args:
  1419. X *    resume - TRUE: resume, FALSE: pause
  1420. X *
  1421. X * Return:
  1422. X *    TRUE - success
  1423. X *    FALSE - failure
  1424. X */
  1425. Xbool_t
  1426. Xnec_pause_resume(bool_t resume)
  1427. X{
  1428. X    if (resume) {
  1429. X        return(
  1430. X            pthru_send(
  1431. X                OP_VN_AUDPLAY, 0, NULL, 0, 0, 0,
  1432. X                (byte_t) (nec_audio_muted ? 0x0 : 0x3),
  1433. X                0x3 << 6, READ_OP
  1434. X            )
  1435. X        );
  1436. X    }
  1437. X    else {
  1438. X        return(
  1439. X            pthru_send(
  1440. X                OP_VN_STILL, 0, NULL, 0, 0, 0,
  1441. X                0, 0, READ_OP
  1442. X            )
  1443. X        );
  1444. X    }
  1445. X}
  1446. X
  1447. X
  1448. X/*
  1449. X * nec_get_playstatus
  1450. X *    Send vendor-unique command to obtain current audio playback
  1451. X *    status.
  1452. X *
  1453. X * Args:
  1454. X *    s - Pointer to the curstat_t structure
  1455. X *    audio_status - Address where a current status code (SCSI-2
  1456. X *               style) is to be returned.
  1457. X *
  1458. X * Return:
  1459. X *    TRUE - success
  1460. X *    FALSE - failure
  1461. X */
  1462. Xbool_t
  1463. Xnec_get_playstatus(curstat_t *s, byte_t *audio_status)
  1464. X{
  1465. X    int        i,
  1466. X            trkno,
  1467. X            idxno;
  1468. X    byte_t        buf[sizeof(nsubq_data_t)];
  1469. X    nsubq_data_t    *d;
  1470. X
  1471. X
  1472. X    memset(buf, (byte_t) 0, sizeof(buf));
  1473. X
  1474. X    if (!pthru_send(OP_VN_RDSUBQ, 0, buf, SZ_VN_RDSUBQ, 0, 0,
  1475. X               SZ_VN_RDSUBQ, 0, READ_OP))
  1476. X        return(FALSE);
  1477. X
  1478. X    d = (nsubq_data_t *)(void *) buf;
  1479. X
  1480. X    trkno = bcdtol((word32_t) d->trkno);
  1481. X    if (s->cur_trk != trkno) {
  1482. X        s->cur_trk = trkno;
  1483. X        dpy_track(s);
  1484. X    }
  1485. X
  1486. X    idxno = bcdtol((word32_t) d->idxno);
  1487. X    if (s->cur_idx != idxno) {
  1488. X        s->cur_idx = idxno;
  1489. X        s->sav_iaddr = s->cur_tot_addr;
  1490. X        dpy_index(s);
  1491. X    }
  1492. X
  1493. X    if ((i = curtrk_pos(s)) >= 0)
  1494. X        s->trkinfo[i].type = (d->trktype == 0) ? TYP_AUDIO : TYP_DATA;
  1495. X
  1496. X    s->cur_tot_min = (byte_t) bcdtol(d->abs_min);
  1497. X    s->cur_tot_sec = (byte_t) bcdtol(d->abs_sec);
  1498. X    s->cur_tot_frame = (byte_t) bcdtol(d->abs_frame);
  1499. X    s->cur_trk_min = (byte_t) bcdtol(d->rel_min);
  1500. X    s->cur_trk_sec = (byte_t) bcdtol(d->rel_sec);
  1501. X    s->cur_trk_frame = (byte_t) bcdtol(d->rel_frame);
  1502. X    msftoblk(
  1503. X        s->cur_tot_min, s->cur_tot_sec, s->cur_tot_frame,
  1504. X        &s->cur_tot_addr, MSF_OFFSET(s)
  1505. X    );
  1506. X    msftoblk(
  1507. X        s->cur_trk_min, s->cur_trk_sec, s->cur_trk_frame,
  1508. X        &s->cur_trk_addr, 0
  1509. X    );
  1510. X
  1511. X    /* Translate NEC audio status to SCSI-2 audio status */
  1512. X    switch (d->audio_status) {
  1513. X    case NAUD_PLAYING:
  1514. X        *audio_status = AUDIO_PLAYING;
  1515. X        break;
  1516. X
  1517. X    case NAUD_PAUSED:
  1518. X    case NAUD_SRCH_PAUSED:
  1519. X        *audio_status = AUDIO_PAUSED;
  1520. X        break;
  1521. X
  1522. X    case NAUD_COMPLETED:
  1523. X        *audio_status = AUDIO_COMPLETED;
  1524. X        break;
  1525. X    }
  1526. X
  1527. X    return(TRUE);
  1528. X}
  1529. X
  1530. X
  1531. X/*
  1532. X * nec_get_toc
  1533. X *    Send vendor-unique command to obtain the disc table-of-contents
  1534. X *
  1535. X * Args:
  1536. X *    s - Pointer to the curstat_t structure, which contains the TOC
  1537. X *        table to be updated.
  1538. X *
  1539. X * Return:
  1540. X *    TRUE - success
  1541. X *    FALSE - failure
  1542. X */
  1543. Xbool_t
  1544. Xnec_get_toc(curstat_t *s)
  1545. X{
  1546. X    int        i,
  1547. X            j;
  1548. X    byte_t        buf[SZ_VN_RDTOC];
  1549. X    ninfo_00_t    *t0;
  1550. X    ninfo_01_t    *t1;
  1551. X    ninfo_02_t    *t2;
  1552. X
  1553. X
  1554. X    memset(buf, (byte_t) 0, sizeof(buf));
  1555. X
  1556. X    /* Find number of tracks */
  1557. X    if (!pthru_send(OP_VN_RDTOC, 0, buf, SZ_VN_RDTOC,
  1558. X            0, 0, 0, 0, READ_OP))
  1559. X        return(FALSE);
  1560. X
  1561. X    t0 = (ninfo_00_t *) buf;
  1562. X    s->first_trk = (byte_t) bcdtol(t0->first_trk);
  1563. X    s->last_trk = (byte_t) bcdtol(t0->last_trk);
  1564. X
  1565. X    /* Get the starting position of each track */
  1566. X    for (i = 0, j = (int) s->first_trk; j <= (int) s->last_trk; i++, j++) {
  1567. X        memset(buf, (byte_t) 0, sizeof(buf));
  1568. X
  1569. X        if (!pthru_send(OP_VN_RDTOC, ltobcd(j) << 24,
  1570. X                buf, SZ_VN_RDTOC, 0, 0, 2,
  1571. X                0, READ_OP))
  1572. X            return(FALSE);
  1573. X
  1574. X        t2 = (ninfo_02_t *) buf;
  1575. X
  1576. X        s->trkinfo[i].trkno = j;
  1577. X        s->trkinfo[i].min = (byte_t) bcdtol(t2->min);
  1578. X        s->trkinfo[i].sec = (byte_t) bcdtol(t2->sec);
  1579. X        s->trkinfo[i].frame = (byte_t) bcdtol(t2->frame);
  1580. X        msftoblk(
  1581. X            s->trkinfo[i].min,
  1582. X            s->trkinfo[i].sec,
  1583. X            s->trkinfo[i].frame,
  1584. X            &s->trkinfo[i].addr,
  1585. X            MSF_OFFSET(s)
  1586. X        );
  1587. X    }
  1588. X    s->tot_trks = (byte_t) i;
  1589. X
  1590. X    memset(buf, (byte_t) 0, sizeof(buf));
  1591. X
  1592. X    /* Get the lead out track position */
  1593. X    if (!pthru_send(OP_VN_RDTOC, 0,
  1594. X            buf, SZ_VN_RDTOC, 0, 0, 1,
  1595. X            0, READ_OP))
  1596. X        return(FALSE);
  1597. X
  1598. X    t1 = (ninfo_01_t *) buf;
  1599. X
  1600. X    s->trkinfo[i].trkno = LEAD_OUT_TRACK;
  1601. X    s->tot_min = s->trkinfo[i].min = (byte_t) bcdtol(t1->min);
  1602. X    s->tot_sec = s->trkinfo[i].sec = (byte_t) bcdtol(t1->sec);
  1603. X    s->tot_frame = s->trkinfo[i].frame = (byte_t) bcdtol(t1->frame);
  1604. X    msftoblk(
  1605. X        s->trkinfo[i].min,
  1606. X        s->trkinfo[i].sec,
  1607. X        s->trkinfo[i].frame,
  1608. X        &s->trkinfo[i].addr,
  1609. X        MSF_OFFSET(s)
  1610. X    );
  1611. X    s->tot_addr = s->trkinfo[i].addr;
  1612. X
  1613. X    return(TRUE);
  1614. X}
  1615. X
  1616. X
  1617. X/*
  1618. X * nec_mute
  1619. X *    Send vendor-unique command to mute/unmute the audio
  1620. X *
  1621. X * Args:
  1622. X *    mute - TRUE: mute audio, FALSE: unmute audio
  1623. X *
  1624. X * Return:
  1625. X *    TRUE - success
  1626. X *    FALSE - failure
  1627. X */
  1628. Xbool_t
  1629. Xnec_mute(bool_t mute)
  1630. X{
  1631. X    curstat_t    *s = curstat_addr();
  1632. X
  1633. X    if (nec_audio_muted != mute) {
  1634. X        switch (s->mode) {
  1635. X        case M_NODISC:
  1636. X        case M_STOP:
  1637. X        case M_PAUSE:
  1638. X            break;
  1639. X
  1640. X        default:
  1641. X            if (!pthru_send(OP_VN_AUDPLAY, 0, NULL, 0, 0, 0,
  1642. X                    (byte_t) (mute ? 0x0 : 0x3),
  1643. X                    0x3 << 6, READ_OP))
  1644. X                return(FALSE);
  1645. X            break;
  1646. X        }
  1647. X
  1648. X        nec_audio_muted = mute;
  1649. X    }
  1650. X
  1651. X    return(TRUE);
  1652. X}
  1653. X
  1654. X
  1655. X/*
  1656. X * nec_eject
  1657. X *    Send vendor-unique command to eject the caddy
  1658. X *
  1659. X * Args:
  1660. X *    Nothing.
  1661. X *
  1662. X * Return:
  1663. X *    TRUE - success
  1664. X *    FALSE - failure
  1665. X */
  1666. Xbool_t
  1667. Xnec_eject(void)
  1668. X{
  1669. X    return(pthru_send(OP_VN_EJECT, 0, NULL, 0, 0, 0, 1, 0, READ_OP));
  1670. X}
  1671. X
  1672. X
  1673. X/*
  1674. X * nec_init
  1675. X *    Initialize the vendor-unique support module
  1676. X *
  1677. X * Args:
  1678. X *    Nothing.
  1679. X *
  1680. X * Return:
  1681. X *    Nothing.
  1682. X */
  1683. Xvoid
  1684. Xnec_init(void)
  1685. X{
  1686. X    /* Do nothing */
  1687. X}
  1688. X
  1689. X
  1690. X/*
  1691. X * nec_halt
  1692. X *    Shut down the vendor-unique support module
  1693. X *
  1694. X * Args:
  1695. X *    Nothing.
  1696. X *
  1697. X * Return:
  1698. X *    Nothing.
  1699. X */
  1700. Xvoid
  1701. Xnec_halt(void)
  1702. X{
  1703. X    /* Do nothing */
  1704. X}
  1705. X
  1706. X#else    /* !NEC */
  1707. X
  1708. X#ifndef LINT
  1709. Xbool_t        lib_nec = FALSE;
  1710. X#endif
  1711. X
  1712. X#endif    /* NEC */
  1713. X
  1714. END_OF_FILE
  1715. if test 9492 -ne `wc -c <'lib_nec.c'`; then
  1716.     echo shar: \"'lib_nec.c'\" unpacked with wrong size!
  1717. fi
  1718. # end of 'lib_nec.c'
  1719. fi
  1720. if test -f 'lib_odt.c' -a "${1}" != "-c" ; then 
  1721.   echo shar: Will not clobber existing file \"'lib_odt.c'\"
  1722. else
  1723. echo shar: Extracting \"'lib_odt.c'\" \(6591 characters\)
  1724. sed "s/^X//" >'lib_odt.c' <<'END_OF_FILE'
  1725. X/*
  1726. X *   xmcd - Motif(tm) CD Audio Player
  1727. X *
  1728. X *   Copyright (C) 1993  Ti Kan
  1729. X *   E-mail: ti@amb.org
  1730. X *
  1731. X *   This program is free software; you can redistribute it and/or modify
  1732. X *   it under the terms of the GNU General Public License as published by
  1733. X *   the Free Software Foundation; either version 2 of the License, or
  1734. X *   (at your option) any later version.
  1735. X *
  1736. X *   This program is distributed in the hope that it will be useful,
  1737. X *   but WITHOUT ANY WARRANTY; without even the implied warranty of
  1738. X *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  1739. X *   GNU General Public License for more details.
  1740. X *
  1741. X *   You should have received a copy of the GNU General Public License
  1742. X *   along with this program; if not, write to the Free Software
  1743. X *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  1744. X *
  1745. X *   This software module contains code that interfaces xmcd to
  1746. X *   the SCO Open Desktop operating system.  The name "SCO" and "ODT"
  1747. X *   are used here for identification purposes.  This software and
  1748. X *   its author are not affiliated with The Santa Cruz Operation, Inc.
  1749. X */
  1750. X#ifndef LINT
  1751. Xstatic char *_lib_odt_c_ident_ = "@(#)lib_odt.c    1.108 93/10/05";
  1752. X#endif
  1753. X
  1754. X#include <Xm/Xm.h>
  1755. X#include "xmcd.h"
  1756. X#include "util.h"
  1757. X#include "cdfunc.h"
  1758. X#include "lib_scsipt.h"
  1759. X
  1760. X#if defined(sco) && !defined(SIMULATED_CDROM)
  1761. X
  1762. X#ifndef OSI_VERS
  1763. X#define OSI_VERS    "1.0"        /* Version */
  1764. X#endif
  1765. X
  1766. X
  1767. Xextern AppData        app_data;
  1768. Xextern bool_t        notrom_error;
  1769. X
  1770. X#ifndef LINT
  1771. Xbool_t            lib_odt = TRUE;
  1772. X#endif
  1773. X
  1774. XSTATIC int        fd = -1;    /* Passthrough device file desc */
  1775. XSTATIC req_sense_data_t    sense_data;    /* Request sense data buffer */
  1776. X
  1777. X
  1778. X/*
  1779. X * pthru_send
  1780. X *    Build SCSI CDB and sent command to the device.
  1781. X *
  1782. X * Args:
  1783. X *    opcode - SCSI command opcode
  1784. X *    addr - The "address" portion of the SCSI CDB
  1785. X *    buf - Pointer to data buffer
  1786. X *    size - Number of bytes to transfer
  1787. X *    rsvd - The "reserved" portion of the SCSI CDB
  1788. X *    length - The "length" portion of the SCSI CDB
  1789. X *    param - The "param" portion of the SCSI CDB
  1790. X *    control - The "control" portion of the SCSI CDB
  1791. X *    rw - Data transfer direction flag (READ_OP or WRITE_OP)
  1792. X *
  1793. X * Return:
  1794. X *    TRUE - command completed successfully
  1795. X *    FALSE - command failed
  1796. X */
  1797. Xbool_t
  1798. Xpthru_send(
  1799. X    byte_t        opcode,
  1800. X    word32_t    addr,
  1801. X    byte_t        *buf,
  1802. X    word32_t    size,
  1803. X    byte_t        rsvd,
  1804. X    word32_t    length,
  1805. X    byte_t        param,
  1806. X    byte_t        control,
  1807. X    byte_t        rw
  1808. X)
  1809. X{
  1810. X    struct scsicmd    sc;
  1811. X    union scsi_cdb    *cdb;
  1812. X
  1813. X    
  1814. X    if (fd < 0 || notrom_error)
  1815. X        return(FALSE);
  1816. X
  1817. X    memset(&sense_data, (byte_t) 0, sizeof(sense_data));
  1818. X    memset(&sc, (byte_t) 0, sizeof(sc));
  1819. X    cdb = (union scsi_cdb *) sc.cdb;
  1820. X
  1821. X    /* set up SCSI CDB */
  1822. X    switch (opcode & 0xf0) {
  1823. X    case 0xa0:
  1824. X    case 0xe0:
  1825. X        /* 12-byte commands */
  1826. X        cdb->twelve.opcode = opcode;
  1827. X        cdb->twelve.misc = param;
  1828. X        cdb->twelve.lun = 0;
  1829. X        CDB12_BLK(&cdb->twelve, bswap32(addr));
  1830. X        CDB12_LEN(&cdb->twelve, bswap32(length));
  1831. X        CDB12_RSV(&cdb->twelve, rsvd);
  1832. X        CDB12_CTL(&cdb->twelve, control);
  1833. X
  1834. X        sc.cdb_len = 12;
  1835. X        break;
  1836. X
  1837. X    case 0xc0:
  1838. X    case 0xd0:
  1839. X    case 0x20:
  1840. X    case 0x30:
  1841. X    case 0x40:
  1842. X        /* 10-byte commands */
  1843. X        cdb->ten.opcode = opcode;
  1844. X        cdb->ten.misc = param;
  1845. X        cdb->ten.lun = 0;
  1846. X        CDB10_BLK(&cdb->ten, bswap32(addr));
  1847. X        CDB10_LEN(&cdb->ten, bswap16((word16_t) length));
  1848. X        CDB10_RSV(&cdb->ten, rsvd);
  1849. X        CDB10_CTL(&cdb->ten, control);
  1850. X
  1851. X        sc.cdb_len = 10;
  1852. X        break;
  1853. X
  1854. X    case 0x00:
  1855. X    case 0x10:
  1856. X        /* 6-byte commands */
  1857. X        cdb->six.opcode = opcode;
  1858. X        cdb->six.misc = param;
  1859. X        cdb->six.lun = 0;
  1860. X        CDB6_BLK(&cdb->six, bswap16((word16_t) addr));
  1861. X        CDB6_LEN(&cdb->six, (byte_t) length);
  1862. X        CDB6_CTL(&cdb->six, control);
  1863. X
  1864. X        sc.cdb_len = 6;
  1865. X        break;
  1866. X
  1867. X    default:
  1868. X        if (app_data.scsierr_msg)
  1869. X            fprintf(stderr, "0x%02x: Unknown SCSI opcode\n",
  1870. X                opcode);
  1871. X        return(FALSE);
  1872. X    }
  1873. X
  1874. X#ifdef DEBUG
  1875. X    {
  1876. X        byte_t    *p = (byte_t *) sc.cdb;
  1877. X        int    i;
  1878. X
  1879. X        fprintf(stderr, "\nSCSI CDB bytes:");
  1880. X        for (i = 0; i < sc.cdb_len; i++, p++)
  1881. X            fprintf(stderr, " %02x", *p);
  1882. X        fprintf(stderr, "\n");
  1883. X    }
  1884. X#endif
  1885. X
  1886. X    /* set up scsicmd */
  1887. X    sc.data_ptr = (faddr_t) buf;
  1888. X    sc.data_len = size;
  1889. X    sc.is_write = (rw == WRITE_OP);
  1890. X
  1891. X    /* Send the command down via the "pass-through" interface */
  1892. X    if (ioctl(fd, SCSIUSERCMD, &sc) < 0) {
  1893. X        perror("SCSIUSERCMD ioctl failed");
  1894. X        return(FALSE);
  1895. X    }
  1896. X
  1897. X    if (sc.host_sts || sc.target_sts) {
  1898. X        if (opcode != OP_S_TEST && app_data.scsierr_msg) {
  1899. X            fprintf(stderr, "%s: %s %s:\n%s=0x%x %s=0x%x %s=0x%x",
  1900. X                PROGNAME,
  1901. X                "SCSI command fault on",
  1902. X                app_data.device,
  1903. X                "Opcode",
  1904. X                opcode,
  1905. X                "Host_status",
  1906. X                sc.host_sts,
  1907. X                "Target_status",
  1908. X                sc.target_sts);
  1909. X        }
  1910. X
  1911. X        /* Send Request Sense command */
  1912. X        cdb->six.opcode = OP_S_RSENSE;
  1913. X        cdb->six.misc = 0;
  1914. X        cdb->six.lun = 0;
  1915. X        CDB6_BLK(&cdb->six, 0);
  1916. X        CDB6_LEN(&cdb->six, SZ_RSENSE);
  1917. X        CDB6_CTL(&cdb->six, 0);
  1918. X        sc.data_ptr = (faddr_t) AD_RSENSE(&sense_data);
  1919. X        sc.data_len = SZ_RSENSE;
  1920. X        sc.is_write = FALSE;
  1921. X        sc.cdb_len = 6;
  1922. X
  1923. X        if (ioctl(fd, SCSIUSERCMD, &sc) < 0 || sense_data.valid == 0) {
  1924. X            if (opcode != OP_S_TEST && app_data.scsierr_msg)
  1925. X                fprintf(stderr, "\n");
  1926. X#ifdef DEBUG
  1927. X            perror("SCSIUSERCMD ioctl (Request Sense) failed");
  1928. X#endif
  1929. X        }
  1930. X        else if (opcode != OP_S_TEST && app_data.scsierr_msg) {
  1931. X            fprintf(stderr, " Key=0x%x Code=0x%x Qual=0x%x\n",
  1932. X                sense_data.key,
  1933. X                sense_data.code,
  1934. X                sense_data.qual);
  1935. X        }
  1936. X
  1937. X        return(FALSE);
  1938. X    }
  1939. X    return(TRUE);
  1940. X}
  1941. X
  1942. X
  1943. X/*
  1944. X * pthru_open
  1945. X *    Open SCSI passthrough device
  1946. X *
  1947. X * Args:
  1948. X *    path - device path name string
  1949. X *
  1950. X * Return:
  1951. X *    TRUE - open successful
  1952. X *    FALSE - open failed
  1953. X */
  1954. Xbool_t
  1955. Xpthru_open(char *path)
  1956. X{
  1957. X    struct stat    stbuf;
  1958. X    char        errstr[STR_BUF_SZ];
  1959. X
  1960. X    /* Check for validity of device node */
  1961. X    if (stat(path, &stbuf) < 0) {
  1962. X        sprintf(errstr, app_data.str_staterr, path);
  1963. X        cd_fatal_popup(app_data.str_fatal, errstr);
  1964. X        return(FALSE);
  1965. X    }
  1966. X    if ((stbuf.st_mode & S_IFMT) != S_IFCHR) {
  1967. X        sprintf(errstr, app_data.str_noderr, path);
  1968. X        cd_fatal_popup(app_data.str_fatal, errstr);
  1969. X        return(FALSE);
  1970. X    }
  1971. X
  1972. X    /* Check for another copy of xmcd running on the same
  1973. X     * CD-ROM device.
  1974. X     */
  1975. X    if (!cd_devlock(path))
  1976. X        return(FALSE);
  1977. X
  1978. X    if ((fd = open(path, O_RDONLY)) < 0)
  1979. X        return(FALSE);
  1980. X
  1981. X    return(TRUE);
  1982. X}
  1983. X
  1984. X
  1985. X/*
  1986. X * pthru_close
  1987. X *    Close SCSI passthrough device
  1988. X *
  1989. X * Args:
  1990. X *    Nothing.
  1991. X *
  1992. X * Return:
  1993. X *    Nothing.
  1994. X */
  1995. Xvoid
  1996. Xpthru_close(void)
  1997. X{
  1998. X    if (fd >= 0) {
  1999. X        close(fd);
  2000. X        fd = -1;
  2001. X    }
  2002. X}
  2003. X
  2004. X
  2005. X/*
  2006. X * pthru_vers
  2007. X *    Return OS Interface Module version string
  2008. X *
  2009. X * Args:
  2010. X *    Nothing.
  2011. X *
  2012. X * Return:
  2013. X *    Module version text string.
  2014. X */
  2015. Xchar *
  2016. Xpthru_vers(void)
  2017. X{
  2018. X    static char    vers[STR_BUF_SZ];
  2019. X
  2020. X    sprintf(vers, "OS Interface module v%s (for SCO ODT)\n", OSI_VERS);
  2021. X    return(vers);
  2022. X}
  2023. X
  2024. X#else    /* !sco || SIMULATED_CDROM */
  2025. X
  2026. X#ifndef LINT
  2027. Xbool_t            lib_odt = FALSE;
  2028. X#endif
  2029. X
  2030. X#endif    /* sco SIMULATED_CDROM */
  2031. X
  2032. X
  2033. END_OF_FILE
  2034. if test 6591 -ne `wc -c <'lib_odt.c'`; then
  2035.     echo shar: \"'lib_odt.c'\" unpacked with wrong size!
  2036. fi
  2037. # end of 'lib_odt.c'
  2038. fi
  2039. if test -f 'lib_pion.c' -a "${1}" != "-c" ; then 
  2040.   echo shar: Will not clobber existing file \"'lib_pion.c'\"
  2041. else
  2042. echo shar: Extracting \"'lib_pion.c'\" \(9566 characters\)
  2043. sed "s/^X//" >'lib_pion.c' <<'END_OF_FILE'
  2044. X/*
  2045. X *   xmcd - Motif(tm) CD Audio Player
  2046. X *
  2047. X *   Copyright (C) 1993  Ti Kan
  2048. X *   E-mail: ti@amb.org
  2049. X *
  2050. X *   This program is free software; you can redistribute it and/or modify
  2051. X *   it under the terms of the GNU General Public License as published by
  2052. X *   the Free Software Foundation; either version 2 of the License, or
  2053. X *   (at your option) any later version.
  2054. X *
  2055. X *   This program is distributed in the hope that it will be useful,
  2056. X *   but WITHOUT ANY WARRANTY; without even the implied warranty of
  2057. X *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  2058. X *   GNU General Public License for more details.
  2059. X *
  2060. X *   You should have received a copy of the GNU General Public License
  2061. X *   along with this program; if not, write to the Free Software
  2062. X *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  2063. X *
  2064. X *   The name "Pioneer" is a trademark of Pioneer Corporation, and is
  2065. X *   used here for identification purposes.  This software and its
  2066. X *   author are not affiliated in any way with Pioneer.
  2067. X *
  2068. X */
  2069. X#ifndef LINT
  2070. Xstatic char *_lib_pion_c_ident_ = "@(#)lib_pion.c    1.25 93/09/28";
  2071. X#endif
  2072. X
  2073. X#include <Xm/Xm.h>
  2074. X#include "xmcd.h"
  2075. X#include "util.h"
  2076. X#include "cdfunc.h"
  2077. X#include "lib_scsipt.h"
  2078. X
  2079. X#ifdef PIONEER
  2080. X
  2081. X
  2082. X#ifndef LINT
  2083. Xbool_t        lib_pion = TRUE;
  2084. X#endif
  2085. X
  2086. X
  2087. X/*
  2088. X * pion_playaudio
  2089. X *    Play audio function: send vendor-unique play audio command
  2090. X *    to the drive.
  2091. X *
  2092. X * Args:
  2093. X *    addr_fmt - Flags indicating which address formats are passed in
  2094. X *    If ADDR_BLK, then:
  2095. X *        start_addr - The logical block starting address
  2096. X *        end_addr - The logical block ending address
  2097. X *    If ADD_MSF, then:
  2098. X *        start_msf - Pointer to the starting MSF address structure
  2099. X *        end_msf - Pointer to the ending MSF address structure
  2100. X *    If ADDR_TRKIDX, then:
  2101. X *        trk - The starting track number
  2102. X *        idx - The starting index number
  2103. X *    If ADDR_OPTEND, then the ending address, if specified, can be
  2104. X *    ignored if possible.
  2105. X *
  2106. X * Return:
  2107. X *    TRUE - success
  2108. X *    FALSE - failure
  2109. X */
  2110. X/*ARGSUSED*/
  2111. Xbool_t
  2112. Xpion_playaudio(
  2113. X    byte_t        addr_fmt,
  2114. X    word32_t    start_addr,
  2115. X    word32_t    end_addr,
  2116. X    msf_t        *start_msf,
  2117. X    msf_t        *end_msf,
  2118. X    byte_t        trk,
  2119. X    byte_t        idx
  2120. X)
  2121. X{
  2122. X    bool_t        ret = FALSE;
  2123. X    word32_t    addr = 0;
  2124. X    paudio_arg_t    *p;
  2125. X
  2126. X    p = (paudio_arg_t *) &addr;
  2127. X
  2128. X    if (!ret && addr_fmt & ADDR_MSF) {
  2129. X        if (addr_fmt & ADDR_OPTEND) {
  2130. X            /* Position laser head at desired location
  2131. X             * and start play.
  2132. X             */
  2133. X            p->addr_min = (byte_t) ltobcd(start_msf->min);
  2134. X            p->addr_sec = (byte_t) ltobcd(start_msf->sec);
  2135. X            p->addr_frame = (byte_t) ltobcd(start_msf->frame);
  2136. X
  2137. X            ret = pthru_send(
  2138. X                OP_VP_AUDSRCH,
  2139. X                addr, NULL, 0, 0, 0,
  2140. X                0x19, 0x1 << 6, READ_OP
  2141. X            );
  2142. X        }
  2143. X        else {
  2144. X            /* Position laser head at desired location */
  2145. X            p->addr_min = (byte_t) ltobcd(start_msf->min);
  2146. X            p->addr_sec = (byte_t) ltobcd(start_msf->sec);
  2147. X            p->addr_frame = (byte_t) ltobcd(start_msf->frame);
  2148. X
  2149. X            if (!pthru_send(OP_VP_AUDSRCH,
  2150. X                    addr, NULL, 0, 0, 0,
  2151. X                    0x9, 0x1 << 6, READ_OP))
  2152. X                return(FALSE);
  2153. X
  2154. X            /* Specify end location and start play */
  2155. X            p->addr_min = (byte_t) ltobcd(end_msf->min);
  2156. X            p->addr_sec = (byte_t) ltobcd(end_msf->sec);
  2157. X            p->addr_frame = (byte_t) ltobcd(end_msf->frame);
  2158. X
  2159. X            ret = pthru_send(
  2160. X                OP_VP_AUDPLAY,
  2161. X                addr, NULL, 0, 0, 0,
  2162. X                0x19, 0x1 << 6, READ_OP
  2163. X            );
  2164. X        }
  2165. X    }
  2166. X
  2167. X    if (!ret && addr_fmt & ADDR_BLK) {
  2168. X        if (addr_fmt & ADDR_OPTEND) {
  2169. X            /* Position laser head at desired location
  2170. X             * and start play.
  2171. X             */
  2172. X            p->addr_logical = start_addr;
  2173. X
  2174. X            ret = pthru_send(
  2175. X                OP_VP_AUDSRCH,
  2176. X                addr, NULL, 0, 0, 0,
  2177. X                0x19, 0x0, READ_OP
  2178. X            );
  2179. X        }
  2180. X        else {
  2181. X            /* Position laser head at desired location */
  2182. X            p->addr_logical = start_addr;
  2183. X
  2184. X            if (!pthru_send(OP_VP_AUDSRCH,
  2185. X                    addr, NULL, 0, 0, 0,
  2186. X                    0x9, 0x0, READ_OP))
  2187. X                return(FALSE);
  2188. X
  2189. X            /* Specify end location and start play */
  2190. X            p->addr_logical = end_addr;
  2191. X
  2192. X            ret = pthru_send(
  2193. X                OP_VP_AUDPLAY,
  2194. X                addr, NULL, 0, 0, 0,
  2195. X                0x19, 0x0, READ_OP
  2196. X            );
  2197. X        }
  2198. X    }
  2199. X
  2200. X    return(ret);
  2201. X}
  2202. X
  2203. X
  2204. X/*
  2205. X * pion_pause_resume
  2206. X *    Pause/resume function: send vendor-unique commands to implement
  2207. X *    the pause and resume capability.
  2208. X *
  2209. X * Args:
  2210. X *    resume - TRUE: resume, FALSE: pause
  2211. X *
  2212. X * Return:
  2213. X *    TRUE - success
  2214. X *    FALSE - failure
  2215. X */
  2216. Xbool_t
  2217. Xpion_pause_resume(bool_t resume)
  2218. X{
  2219. X    if (resume) {
  2220. X        return(
  2221. X            pthru_send(
  2222. X                OP_VP_PAUSE, 0, NULL, 0, 0, 0,
  2223. X                0x0, 0, READ_OP
  2224. X            )
  2225. X        );
  2226. X    }
  2227. X    else {
  2228. X        return(
  2229. X            pthru_send(
  2230. X                OP_VP_PAUSE, 0, NULL, 0, 0, 0,
  2231. X                0x1 << 4, 0, READ_OP
  2232. X            )
  2233. X        );
  2234. X    }
  2235. X}
  2236. X
  2237. X
  2238. X/*
  2239. X * pion_get_playstatus
  2240. X *    Send vendor-unique command to obtain current audio playback
  2241. X *    status.
  2242. X *
  2243. X * Args:
  2244. X *    s - Pointer to the curstat_t structure
  2245. X *    audio_status - Address where a current status code (SCSI-2
  2246. X *               style) is to be returned.
  2247. X *
  2248. X * Return:
  2249. X *    TRUE - success
  2250. X *    FALSE - failure
  2251. X */
  2252. Xbool_t
  2253. Xpion_get_playstatus(curstat_t *s, byte_t *audio_status)
  2254. X{
  2255. X    int            i,
  2256. X                trkno,
  2257. X                idxno;
  2258. X    byte_t            buf[sizeof(psubq_data_t)];
  2259. X    bool_t            stopped;
  2260. X    paudstat_data_t        *a;
  2261. X    psubq_data_t        *d;
  2262. X
  2263. X
  2264. X    memset(buf, (byte_t) 0, sizeof(buf));
  2265. X
  2266. X    /* Send Pioneer Read Audio Status command */
  2267. X    if (!pthru_send(OP_VP_AUDSTAT, 0, AD_VP_AUDSTAT(buf), SZ_VP_AUDSTAT,
  2268. X            0, SZ_VP_AUDSTAT, 0, 0, READ_OP))
  2269. X        return(FALSE);
  2270. X
  2271. X    a = (paudstat_data_t *)(void *) buf;
  2272. X
  2273. X    stopped = FALSE;
  2274. X
  2275. X    /* Translate Pioneer audio status to SCSI-2 audio status */
  2276. X    switch (a->status) {
  2277. X    case PAUD_PLAYING:
  2278. X    case PAUD_MUTEPLAY:
  2279. X        *audio_status = AUDIO_PLAYING;
  2280. X        break;
  2281. X
  2282. X    case PAUD_PAUSED:
  2283. X        *audio_status = AUDIO_PAUSED;
  2284. X        break;
  2285. X
  2286. X    case PAUD_COMPLETED:
  2287. X        *audio_status = AUDIO_COMPLETED;
  2288. X        stopped = TRUE;
  2289. X        break;
  2290. X
  2291. X    case PAUD_ERROR:
  2292. X        *audio_status = AUDIO_FAILED;
  2293. X        stopped = TRUE;
  2294. X        break;
  2295. X
  2296. X    case PAUD_NOSTATUS:
  2297. X        *audio_status = AUDIO_NOSTATUS;
  2298. X        stopped = TRUE;
  2299. X        break;
  2300. X    }
  2301. X
  2302. X    if (stopped) {
  2303. X        s->cur_tot_min = (byte_t) bcdtol(a->abs_min);
  2304. X        s->cur_tot_sec = (byte_t) bcdtol(a->abs_sec);
  2305. X        s->cur_tot_frame = (byte_t) bcdtol(a->abs_frame);
  2306. X
  2307. X        if ((i = curtrk_pos(s)) >= 0)
  2308. X            s->trkinfo[i].type =
  2309. X                (a->trktype == 0) ? TYP_AUDIO : TYP_DATA;
  2310. X
  2311. X        return(TRUE);
  2312. X    }
  2313. X
  2314. X    memset(buf, (byte_t) 0, sizeof(buf));
  2315. X
  2316. X    /* Send Pioneer Read Subcode Q command */
  2317. X    if (!pthru_send(OP_VP_RDSUBQ, 0, AD_VP_SUBQ(buf), SZ_VP_RDSUBQ,
  2318. X            0, SZ_VP_RDSUBQ, 0, 0, READ_OP))
  2319. X        return(FALSE);
  2320. X
  2321. X    d = (psubq_data_t *)(void *) buf;
  2322. X
  2323. X    trkno = bcdtol((word32_t) d->trkno);
  2324. X    if (s->cur_trk != trkno) {
  2325. X        s->cur_trk = trkno;
  2326. X        dpy_track(s);
  2327. X    }
  2328. X
  2329. X    idxno = bcdtol((word32_t) d->idxno);
  2330. X    if (s->cur_idx != idxno) {
  2331. X        s->cur_idx = idxno;
  2332. X        s->sav_iaddr = s->cur_tot_addr;
  2333. X        dpy_index(s);
  2334. X    }
  2335. X
  2336. X    if ((i = curtrk_pos(s)) >= 0)
  2337. X        s->trkinfo[i].type =
  2338. X            (d->trktype == 0) ? TYP_AUDIO : TYP_DATA;
  2339. X
  2340. X    s->cur_tot_min = (byte_t) bcdtol(d->abs_min);
  2341. X    s->cur_tot_sec = (byte_t) bcdtol(d->abs_sec);
  2342. X    s->cur_tot_frame = (byte_t) bcdtol(d->abs_frame);
  2343. X    s->cur_trk_min = (byte_t) bcdtol(d->rel_min);
  2344. X    s->cur_trk_sec = (byte_t) bcdtol(d->rel_sec);
  2345. X    s->cur_trk_frame = (byte_t) bcdtol(d->rel_frame);
  2346. X    msftoblk(
  2347. X        s->cur_tot_min, s->cur_tot_sec, s->cur_tot_frame,
  2348. X        &s->cur_tot_addr, MSF_OFFSET(s)
  2349. X    );
  2350. X    msftoblk(
  2351. X        s->cur_trk_min, s->cur_trk_sec, s->cur_trk_frame,
  2352. X        &s->cur_trk_addr, 0
  2353. X    );
  2354. X
  2355. X    return(TRUE);
  2356. X}
  2357. X
  2358. X
  2359. X/*
  2360. X * pion_get_toc
  2361. X *    Send vendor-unique command to obtain the disc table-of-contents
  2362. X *
  2363. X * Args:
  2364. X *    s - Pointer to the curstat_t structure, which contains the TOC
  2365. X *        table to be updated.
  2366. X *
  2367. X * Return:
  2368. X *    TRUE - success
  2369. X *    FALSE - failure
  2370. X */
  2371. Xbool_t
  2372. Xpion_get_toc(curstat_t *s)
  2373. X{
  2374. X    int        i,
  2375. X            j;
  2376. X    byte_t        buf[SZ_VP_RDTOC];
  2377. X    pinfo_00_t    *t0;
  2378. X    pinfo_01_t    *t1;
  2379. X    pinfo_02_t    *t2;
  2380. X
  2381. X
  2382. X    memset(buf, (byte_t) 0, sizeof(buf));
  2383. X
  2384. X    /* Find number of tracks */
  2385. X    if (!pthru_send(OP_VP_RDTOC, 0, buf, SZ_VP_RDTOC,
  2386. X            0, SZ_VP_RDTOC, 0, 0, READ_OP))
  2387. X        return(FALSE);
  2388. X
  2389. X    t0 = (pinfo_00_t *) buf;
  2390. X    s->first_trk = (byte_t) bcdtol(t0->first_trk);
  2391. X    s->last_trk = (byte_t) bcdtol(t0->last_trk);
  2392. X
  2393. X    /* Get the starting position of each track */
  2394. X    for (i = 0, j = (int) s->first_trk; j <= (int) s->last_trk; i++, j++) {
  2395. X        if (!pthru_send(OP_VP_RDTOC, ltobcd(j),
  2396. X                buf, SZ_VP_RDTOC, 0, SZ_VP_RDTOC, 0,
  2397. X                0x2 << 6, READ_OP))
  2398. X            return(FALSE);
  2399. X
  2400. X        t2 = (pinfo_02_t *)(void *) buf;
  2401. X
  2402. X        s->trkinfo[i].trkno = j;
  2403. X        s->trkinfo[i].min = (byte_t) bcdtol(t2->min);
  2404. X        s->trkinfo[i].sec = (byte_t) bcdtol(t2->sec);
  2405. X        s->trkinfo[i].frame = (byte_t) bcdtol(t2->frame);
  2406. X        msftoblk(
  2407. X            s->trkinfo[i].min,
  2408. X            s->trkinfo[i].sec,
  2409. X            s->trkinfo[i].frame,
  2410. X            &s->trkinfo[i].addr,
  2411. X            MSF_OFFSET(s)
  2412. X        );
  2413. X    }
  2414. X    s->tot_trks = (byte_t) i;
  2415. X
  2416. X    /* Get the lead out track position */
  2417. X    if (!pthru_send(OP_VP_RDTOC, 0,
  2418. X            buf, SZ_VP_RDTOC, 0, SZ_VP_RDTOC, 0,
  2419. X            0x1 << 6, READ_OP))
  2420. X        return(FALSE);
  2421. X
  2422. X    t1 = (pinfo_01_t *) buf;
  2423. X
  2424. X    s->trkinfo[i].trkno = LEAD_OUT_TRACK;
  2425. X    s->tot_min = s->trkinfo[i].min = (byte_t) bcdtol(t1->min);
  2426. X    s->tot_sec = s->trkinfo[i].sec = (byte_t) bcdtol(t1->sec);
  2427. X    s->tot_frame = s->trkinfo[i].frame = (byte_t) bcdtol(t1->frame);
  2428. X    msftoblk(
  2429. X        s->trkinfo[i].min,
  2430. X        s->trkinfo[i].sec,
  2431. X        s->trkinfo[i].frame,
  2432. X        &s->trkinfo[i].addr,
  2433. X        MSF_OFFSET(s)
  2434. X    );
  2435. X    s->tot_addr = s->trkinfo[i].addr;
  2436. X
  2437. X    return(TRUE);
  2438. X}
  2439. X
  2440. X
  2441. X/*
  2442. X * pion_eject
  2443. X *    Send vendor-unique command to eject the caddy
  2444. X *
  2445. X * Args:
  2446. X *    Nothing.
  2447. X *
  2448. X * Return:
  2449. X *    TRUE - success
  2450. X *    FALSE - failure
  2451. X */
  2452. Xbool_t
  2453. Xpion_eject(void)
  2454. X{
  2455. X    return(pthru_send(OP_VP_EJECT, 0, NULL, 0, 0, 0, 1, 0, READ_OP));
  2456. X}
  2457. X
  2458. X
  2459. X/*
  2460. X * pion_init
  2461. X *    Initialize the vendor-unique support module
  2462. X *
  2463. X * Args:
  2464. X *    Nothing.
  2465. X *
  2466. X * Return:
  2467. X *    Nothing.
  2468. X */
  2469. Xvoid
  2470. Xpion_init(void)
  2471. X{
  2472. X    /* Do nothing */
  2473. X}
  2474. X
  2475. X
  2476. X/*
  2477. X * pion_halt
  2478. X *    Shut down the vendor-unique support module
  2479. X *
  2480. X * Args:
  2481. X *    Nothing.
  2482. X *
  2483. X * Return:
  2484. X *    Nothing.
  2485. X */
  2486. Xvoid
  2487. Xpion_halt(void)
  2488. X{
  2489. X    /* Do nothing */
  2490. X}
  2491. X
  2492. X#else    /* !PIONEER */
  2493. X
  2494. X#ifndef LINT
  2495. Xbool_t        lib_pion = TRUE;
  2496. X#endif
  2497. X
  2498. X#endif    /* PIONEER */
  2499. X
  2500. END_OF_FILE
  2501. if test 9566 -ne `wc -c <'lib_pion.c'`; then
  2502.     echo shar: \"'lib_pion.c'\" unpacked with wrong size!
  2503. fi
  2504. # end of 'lib_pion.c'
  2505. fi
  2506. if test -f 'lib_sim.c' -a "${1}" != "-c" ; then 
  2507.   echo shar: Will not clobber existing file \"'lib_sim.c'\"
  2508. else
  2509. echo shar: Extracting \"'lib_sim.c'\" \(18785 characters\)
  2510. sed "s/^X//" >'lib_sim.c' <<'END_OF_FILE'
  2511. X/*
  2512. X *   xmcd - Motif(tm) CD Audio Player
  2513. X *
  2514. X *   Copyright (C) 1993  Ti Kan
  2515. X *   E-mail: ti@amb.org
  2516. X *
  2517. X *   This program is free software; you can redistribute it and/or modify
  2518. X *   it under the terms of the GNU General Public License as published by
  2519. X *   the Free Software Foundation; either version 2 of the License, or
  2520. X *   (at your option) any later version.
  2521. X *
  2522. X *   This program is distributed in the hope that it will be useful,
  2523. X *   but WITHOUT ANY WARRANTY; without even the implied warranty of
  2524. X *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  2525. X *   GNU General Public License for more details.
  2526. X *
  2527. X *   You should have received a copy of the GNU General Public License
  2528. X *   along with this program; if not, write to the Free Software
  2529. X *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  2530. X *
  2531. X */
  2532. X#ifndef LINT
  2533. Xstatic char *_lib_sim_c_ident_ = "@(#)lib_sim.c    1.26 93/09/28";
  2534. X#endif
  2535. X
  2536. X#include "xmcd.h"
  2537. X#include "util.h"
  2538. X#include "lib_scsipt.h"
  2539. X
  2540. X
  2541. X#ifdef SIMULATED_CDROM
  2542. X
  2543. X#ifndef CDSIM_VERS
  2544. X#define CDSIM_VERS        "1.00"    /* CD-ROM simulator version */
  2545. X#endif
  2546. X
  2547. Xextern int            cdsim_sfd[],
  2548. X                cdsim_rfd[];
  2549. X
  2550. X#ifndef LINT
  2551. Xbool_t                lib_sim = TRUE;
  2552. X#endif
  2553. X
  2554. XSTATIC simstat_t        cdsim_stat;
  2555. XSTATIC time_t            cdsim_start_time = 0,
  2556. X                cdsim_pause_time = 0,
  2557. X                cdsim_pause_elapsed = 0,
  2558. X                cdsim_prev_pause = 0,
  2559. X                cdsim_elapsed = 0,
  2560. X                cdsim_now;
  2561. X
  2562. XSTATIC inquiry_data_t        cdsim_inqdata;
  2563. XSTATIC byte_t            cdsim_tocdata1[SZ_RDTOC],
  2564. X                cdsim_tocdata2[SZ_RDTOC];
  2565. X
  2566. X
  2567. X
  2568. X/*
  2569. X * cdsim_sendpkt
  2570. X *    Write a CD simulator packet down the pipe
  2571. X *
  2572. X * Args:
  2573. X *    name - The text string describing the caller module
  2574. X *    fd - Pipe file descriptor
  2575. X *    s - Pointer to the packet data
  2576. X *
  2577. X * Return:
  2578. X *    TRUE - pipe write successful
  2579. X *    FALSE - pipe write failed
  2580. X */
  2581. Xbool_t
  2582. Xcdsim_sendpkt(char *name, int fd, simpkt_t *s)
  2583. X{
  2584. X    byte_t    *p = (byte_t *) s;
  2585. X    int    i,
  2586. X        ret;
  2587. X
  2588. X    if (fd < 0)
  2589. X        return(FALSE);
  2590. X
  2591. X    /* Brand packet with magic number */
  2592. X    s->magic = CDSIM_MAGIC;
  2593. X
  2594. X    /* Send a packet */
  2595. X    i = CDSIM_PKTSZ;
  2596. X    while ((ret = write(fd, p, i)) < i) {
  2597. X        if (ret < 0 && errno != EBADF) {
  2598. X            fprintf(stderr, "%s: packet write error (errno=%d)\n",
  2599. X                name, errno);
  2600. X            return(FALSE);
  2601. X        }
  2602. X
  2603. X        i -= ret;
  2604. X        p += ret;
  2605. X    }
  2606. X
  2607. X    return(TRUE);
  2608. X}
  2609. X
  2610. X
  2611. X/*
  2612. X * cdsim_getpkt
  2613. X *    Read a CD simulator packet from the pipe
  2614. X *
  2615. X * Args:
  2616. X *    name - The text string describing the caller module
  2617. X *    fd - Pipe file descriptor
  2618. X *    s - Pointer to the packet data
  2619. X *
  2620. X * Return:
  2621. X *    TRUE - pipe read successful
  2622. X *    FALSE - pipe read failed
  2623. X */
  2624. Xbool_t
  2625. Xcdsim_getpkt(char *name, int fd, simpkt_t *r)
  2626. X{
  2627. X    byte_t    *p = (byte_t *) r;
  2628. X    int    i,
  2629. X        ret;
  2630. X
  2631. X    if (fd < 0)
  2632. X        return(FALSE);
  2633. X
  2634. X    /* Get a packet */
  2635. X    i = CDSIM_PKTSZ;
  2636. X    while ((ret = read(fd, p, i)) < i) {
  2637. X        if (ret < 0 && errno != EBADF) {
  2638. X            fprintf(stderr, "%s: packet read error (errno=%d)\n",
  2639. X                name, errno);
  2640. X            return(FALSE);
  2641. X        }
  2642. X
  2643. X        i -= ret;
  2644. X        p += ret;
  2645. X    }
  2646. X
  2647. X    /* Check packet for magic number */
  2648. X    if (r->magic != CDSIM_MAGIC) {
  2649. X        fprintf(stderr, "%s: bad packet magic number.\n", name);
  2650. X        return(FALSE);
  2651. X    }
  2652. X
  2653. X    return(TRUE);
  2654. X}
  2655. X
  2656. X
  2657. X/*
  2658. X * cdsim_sig
  2659. X *    CD simulator process signal handler
  2660. X *
  2661. X * Args:
  2662. X *    sig - The signal number
  2663. X *
  2664. X * Return:
  2665. X *    Nothing.
  2666. X */
  2667. X/*ARGSUSED*/
  2668. XSTATIC void
  2669. Xcdsim_sig(int sig)
  2670. X{
  2671. X    fprintf(stderr, "CD-ROM simulator exiting.\n");
  2672. X    exit(0);
  2673. X}
  2674. X
  2675. X
  2676. X/*
  2677. X * cdsim_s_test
  2678. X *    Test Unit Ready command simulation function
  2679. X *
  2680. X * Args:
  2681. X *    r - Pointer to the command packet
  2682. X *    s - Pointer to the response packet
  2683. X *
  2684. X * Return:
  2685. X *    Command completion status code
  2686. X */
  2687. X/*ARGSUSED*/
  2688. XSTATIC word32_t
  2689. Xcdsim_s_test(simpkt_t *r, simpkt_t *s)
  2690. X{
  2691. X    if (cdsim_stat.status == CDSIM_NODISC)
  2692. X        return(CDSIM_COMPERR);
  2693. X    else
  2694. X        return(CDSIM_COMPOK);
  2695. X}
  2696. X
  2697. X
  2698. X/*
  2699. X * cdsim_s_inquir
  2700. X *    Inquiry command simulation function
  2701. X *
  2702. X * Args:
  2703. X *    r - Pointer to the command packet
  2704. X *    s - Pointer to the response packet
  2705. X *
  2706. X * Return:
  2707. X *    Command completion status code
  2708. X */
  2709. XSTATIC 
  2710. Xcdsim_s_inquir(simpkt_t *r, simpkt_t *s)
  2711. X{
  2712. X    s->len = (r->len > CDSIM_INQSZ) ? CDSIM_INQSZ : r->len;
  2713. X
  2714. X    /* Copy inquiry data into packet */
  2715. X    memcpy(s->data, (byte_t *) &cdsim_inqdata, s->len);
  2716. X
  2717. X    return(CDSIM_COMPOK);
  2718. X}
  2719. X
  2720. X
  2721. X/*
  2722. X * cdsim_s_mselect
  2723. X *    Mode Select command simulation function
  2724. X *
  2725. X * Args:
  2726. X *    r - Pointer to the command packet
  2727. X *    s - Pointer to the response packet
  2728. X *
  2729. X * Return:
  2730. X *    Command completion status code
  2731. X */
  2732. X/*ARGSUSED*/
  2733. XSTATIC 
  2734. Xcdsim_s_mselect(simpkt_t *r, simpkt_t *s)
  2735. X{
  2736. X    return(CDSIM_COMPOK);
  2737. X}
  2738. X
  2739. X
  2740. X/*
  2741. X * cdsim_s_msense
  2742. X *    Mode Sense command simulation function
  2743. X *
  2744. X * Args:
  2745. X *    r - Pointer to the command packet
  2746. X *    s - Pointer to the response packet
  2747. X *
  2748. X * Return:
  2749. X *    Command completion status code
  2750. X */
  2751. X/*ARGSUSED*/
  2752. XSTATIC 
  2753. Xcdsim_s_msense(simpkt_t *r, simpkt_t *s)
  2754. X{
  2755. X    return(CDSIM_COMPOK);
  2756. X}
  2757. X
  2758. X
  2759. X/*
  2760. X * cdsim_s_start
  2761. X *    Start/Stop Unit command simulation function
  2762. X *
  2763. X * Args:
  2764. X *    r - Pointer to the command packet
  2765. X *    s - Pointer to the response packet
  2766. X *
  2767. X * Return:
  2768. X *    Command completion status code
  2769. X */
  2770. X/*ARGSUSED*/
  2771. XSTATIC
  2772. Xcdsim_s_start(simpkt_t *r, simpkt_t *s)
  2773. X{
  2774. X    cdsim_start_time = 0;
  2775. X    cdsim_elapsed = 0;
  2776. X    cdsim_pause_time = 0;
  2777. X    cdsim_pause_elapsed = 0;
  2778. X    cdsim_prev_pause = 0;
  2779. X
  2780. X    if (r->cdb[4] & 0x01) {
  2781. X        /* Start unit */
  2782. X        if (r->cdb[4] & 0x02) {
  2783. X            /* Load disc */
  2784. X            cdsim_stat.status = CDSIM_STOPPED;
  2785. X            return(CDSIM_COMPOK);
  2786. X        }
  2787. X        else if (cdsim_stat.status == CDSIM_NODISC)
  2788. X            return(CDSIM_COMPERR);
  2789. X    }
  2790. X    else {
  2791. X        /* Stop unit */
  2792. X        if (cdsim_stat.status == CDSIM_NODISC)
  2793. X            return(CDSIM_COMPERR);
  2794. X        else if (r->cdb[4] & 0x02) {
  2795. X            /* Eject disc */
  2796. X            if (cdsim_stat.caddylock)
  2797. X                return(CDSIM_COMPERR);
  2798. X            else {
  2799. X                cdsim_stat.status = CDSIM_NODISC;
  2800. X                return(CDSIM_COMPOK);
  2801. X            }
  2802. X        }
  2803. X        else {
  2804. X            /* Stop disc */
  2805. X            cdsim_stat.status = CDSIM_STOPPED;
  2806. X            return(CDSIM_COMPOK);
  2807. X        }
  2808. X    }
  2809. X    return(CDSIM_COMPOK);
  2810. X}
  2811. X
  2812. X
  2813. X/*
  2814. X * cdsim_s_prevent
  2815. X *    Prevent/Allow Medium Removal command simulation function
  2816. X *
  2817. X * Args:
  2818. X *    r - Pointer to the command packet
  2819. X *    s - Pointer to the response packet
  2820. X *
  2821. X * Return:
  2822. X *    Command completion status code
  2823. X */
  2824. X/*ARGSUSED*/
  2825. XSTATIC
  2826. Xcdsim_s_prevent(simpkt_t *r, simpkt_t *s)
  2827. X{
  2828. X    if (r->cdb[4] & 0x01)
  2829. X        cdsim_stat.caddylock = TRUE;
  2830. X    else
  2831. X        cdsim_stat.caddylock = FALSE;
  2832. X
  2833. X    return(CDSIM_COMPOK);
  2834. X}
  2835. X
  2836. X
  2837. X/*
  2838. X * cdsim_m_rdsubq
  2839. X *    Read Subchannel command simulation function
  2840. X *
  2841. X * Args:
  2842. X *    r - Pointer to the command packet
  2843. X *    s - Pointer to the response packet
  2844. X *
  2845. X * Return:
  2846. X *    Command completion status code
  2847. X */
  2848. XSTATIC
  2849. Xcdsim_m_rdsubq(simpkt_t *r, simpkt_t *s)
  2850. X{
  2851. X    subq_hdr_t    *h = (subq_hdr_t *)(void *) s->data;
  2852. X    subq_01_t    *s1 = (subq_01_t *)(void *)
  2853. X                  (s->data + sizeof(subq_hdr_t));
  2854. X
  2855. X    /* Subchannel formats */
  2856. X    switch (r->cdb[3]) {
  2857. X    case SUB_CURPOS:
  2858. X        h->subch_len = 15;
  2859. X
  2860. X        s1->fmt_code = SUB_CURPOS;
  2861. X        s1->preemph = 0;
  2862. X        s1->copyallow = 0;
  2863. X        s1->trktype = 0;
  2864. X        s1->audioch = 0;
  2865. X        s1->adr = 0;
  2866. X
  2867. X        s1->trkno = cdsim_stat.trkno;
  2868. X        s1->idxno = cdsim_stat.idxno;
  2869. X
  2870. X        if (r->cdb[1] & 0x02) {
  2871. X            blktomsf(
  2872. X                cdsim_stat.absaddr,
  2873. X                &s1->abs_addr.msf.min,
  2874. X                &s1->abs_addr.msf.sec,
  2875. X                &s1->abs_addr.msf.frame,
  2876. X                FRAME_PER_SEC << 1
  2877. X            );
  2878. X
  2879. X            blktomsf(
  2880. X                cdsim_stat.reladdr,
  2881. X                &s1->rel_addr.msf.min,
  2882. X                &s1->rel_addr.msf.sec,
  2883. X                &s1->rel_addr.msf.frame,
  2884. X                0
  2885. X            );
  2886. X        }
  2887. X        else {
  2888. X            s1->abs_addr.logical = bswap32(cdsim_stat.absaddr);
  2889. X            s1->rel_addr.logical = bswap32(cdsim_stat.reladdr);
  2890. X        }
  2891. X
  2892. X        s->len = sizeof(subq_hdr_t) + sizeof(subq_01_t);
  2893. X
  2894. X        break;
  2895. X
  2896. X    default:
  2897. X        /* The other formats are not implemented */
  2898. X        return(CDSIM_COMPERR);
  2899. X    }
  2900. X
  2901. X    switch (cdsim_stat.status) {
  2902. X    case CDSIM_PLAYING:
  2903. X        h->audio_status = AUDIO_PLAYING;
  2904. X        break;
  2905. X
  2906. X    case CDSIM_PAUSED:
  2907. X        h->audio_status = AUDIO_PAUSED;
  2908. X        break;
  2909. X
  2910. X    default:
  2911. X        h->audio_status = AUDIO_COMPLETED;
  2912. X        break;
  2913. X    }
  2914. X
  2915. X    return(CDSIM_COMPOK);
  2916. X}
  2917. X
  2918. X
  2919. X/*
  2920. X * cdsim_m_rdtoc
  2921. X *    Read TOC command simulation function
  2922. X *
  2923. X * Args:
  2924. X *    r - Pointer to the command packet
  2925. X *    s - Pointer to the response packet
  2926. X *
  2927. X * Return:
  2928. X *    Command completion status code
  2929. X */
  2930. XSTATIC
  2931. Xcdsim_m_rdtoc(simpkt_t *r, simpkt_t *s)
  2932. X{
  2933. X    byte_t    *startoff;
  2934. X
  2935. X    if (r->cdb[1] & 0x02)
  2936. X        startoff = cdsim_tocdata2 + sizeof(toc_hdr_t);
  2937. X    else
  2938. X        startoff = cdsim_tocdata1 + sizeof(toc_hdr_t);
  2939. X
  2940. X    s->len = (r->len > SZ_RDTOC) ? SZ_RDTOC : r->len;
  2941. X
  2942. X    if (r->cdb[6] > 1) {
  2943. X        int    skip;
  2944. X
  2945. X        skip = ((int) r->cdb[6] - 1) *
  2946. X            sizeof(toc_trk_descr_t);
  2947. X        s->len -= skip;
  2948. X        startoff += skip;
  2949. X    }
  2950. X
  2951. X    /* Copy TOC data into packet */
  2952. X
  2953. X    /* Header info */
  2954. X    memcpy(s->data, cdsim_tocdata1, sizeof(toc_hdr_t));
  2955. X
  2956. X    /* TOC data */
  2957. X    memcpy(s->data + sizeof(toc_hdr_t), startoff, s->len);
  2958. X
  2959. X    return(CDSIM_COMPOK);
  2960. X}
  2961. X
  2962. X
  2963. X/*
  2964. X * cdsim_m_play
  2965. X *    Play Audio (10) command simulation function
  2966. X *
  2967. X * Args:
  2968. X *    r - Pointer to the command packet
  2969. X *    s - Pointer to the response packet
  2970. X *
  2971. X * Return:
  2972. X *    Command completion status code
  2973. X */
  2974. X/*ARGSUSED*/
  2975. XSTATIC
  2976. Xcdsim_m_play(simpkt_t *r, simpkt_t *s)
  2977. X{
  2978. X    cdsim_stat.startaddr = (r->cdb[2] << 24) | (r->cdb[3] << 16) |
  2979. X        (r->cdb[4] << 8) | r->cdb[5];
  2980. X    cdsim_stat.endaddr = cdsim_stat.startaddr +
  2981. X        ((r->cdb[7] << 8) | r->cdb[8]);
  2982. X
  2983. X    if (cdsim_stat.endaddr <= cdsim_stat.startaddr)
  2984. X        return(CDSIM_PARMERR);
  2985. X
  2986. X    cdsim_start_time = cdsim_now;
  2987. X    cdsim_elapsed = 0;
  2988. X    cdsim_pause_time = 0;
  2989. X    cdsim_pause_elapsed = 0;
  2990. X    cdsim_prev_pause = 0;
  2991. X
  2992. X    cdsim_stat.status = CDSIM_PLAYING;
  2993. X
  2994. X    return(CDSIM_COMPOK);
  2995. X}
  2996. X
  2997. X
  2998. X/*
  2999. X * cdsim_m_playmsf
  3000. X *    Play Audio MSF command simulation function
  3001. X *
  3002. X * Args:
  3003. X *    r - Pointer to the command packet
  3004. X *    s - Pointer to the response packet
  3005. X *
  3006. X * Return:
  3007. X *    Command completion status code
  3008. X */
  3009. X/*ARGSUSED*/
  3010. XSTATIC
  3011. Xcdsim_m_playmsf(simpkt_t *r, simpkt_t *s)
  3012. X{
  3013. X    msftoblk(r->cdb[3], r->cdb[4], r->cdb[5], &cdsim_stat.startaddr,
  3014. X         FRAME_PER_SEC << 1);
  3015. X    msftoblk(r->cdb[6], r->cdb[7], r->cdb[8], &cdsim_stat.endaddr,
  3016. X         FRAME_PER_SEC << 1);
  3017. X
  3018. X    if (cdsim_stat.endaddr <= cdsim_stat.startaddr)
  3019. X        return(CDSIM_PARMERR);
  3020. X
  3021. X    cdsim_start_time = cdsim_now;
  3022. X    cdsim_elapsed = 0;
  3023. X    cdsim_pause_time = 0;
  3024. X    cdsim_pause_elapsed = 0;
  3025. X    cdsim_prev_pause = 0;
  3026. X
  3027. X    cdsim_stat.status = CDSIM_PLAYING;
  3028. X
  3029. X    return(CDSIM_COMPOK);
  3030. X}
  3031. X
  3032. X
  3033. X/*
  3034. X * cdsim_m_playti
  3035. X *    Play Audio Track/index command simulation function
  3036. X *
  3037. X * Args:
  3038. X *    r - Pointer to the command packet
  3039. X *    s - Pointer to the response packet
  3040. X *
  3041. X * Return:
  3042. X *    Command completion status code
  3043. X */
  3044. X/*ARGSUSED*/
  3045. XSTATIC
  3046. Xcdsim_m_playti(simpkt_t *r, simpkt_t *s)
  3047. X{
  3048. X    int    strk = (int) r->cdb[4],
  3049. X        sidx = (int) r->cdb[5],
  3050. X        etrk = (int) r->cdb[7],
  3051. X        eidx = (int) r->cdb[8];
  3052. X
  3053. X    if (sidx > (int) cdsim_stat.trk[strk - 1].nidxs) {
  3054. X        strk++;
  3055. X        sidx = 1;
  3056. X    }
  3057. X
  3058. X    if (strk > (int) cdsim_stat.ntrks || etrk > (int) cdsim_stat.ntrks)
  3059. X        return(CDSIM_PARMERR);
  3060. X
  3061. X    if (eidx > (int) cdsim_stat.trk[strk - 1].nidxs)
  3062. X        eidx = (int) cdsim_stat.trk[strk - 1].nidxs;
  3063. X
  3064. X    cdsim_stat.startaddr = cdsim_stat.trk[strk - 1].iaddr[sidx - 1];
  3065. X    cdsim_stat.endaddr = cdsim_stat.trk[etrk].iaddr[eidx];
  3066. X
  3067. X    if (cdsim_stat.endaddr <= cdsim_stat.startaddr)
  3068. X        return(CDSIM_PARMERR);
  3069. X
  3070. X    cdsim_start_time = cdsim_now;
  3071. X    cdsim_elapsed = 0;
  3072. X    cdsim_pause_time = 0;
  3073. X    cdsim_pause_elapsed = 0;
  3074. X    cdsim_prev_pause = 0;
  3075. X
  3076. X    cdsim_stat.status = CDSIM_PLAYING;
  3077. X
  3078. X    return(CDSIM_COMPOK);
  3079. X}
  3080. X
  3081. X
  3082. X/*
  3083. X * cdsim_m_pause
  3084. X *    Pause/Resume command simulation function
  3085. X *
  3086. X * Args:
  3087. X *    r - Pointer to the command packet
  3088. X *    s - Pointer to the response packet
  3089. X *
  3090. X * Return:
  3091. X *    Command completion status code
  3092. X */
  3093. X/*ARGSUSED*/
  3094. XSTATIC
  3095. Xcdsim_m_pause(simpkt_t *r, simpkt_t *s)
  3096. X{
  3097. X    if (cdsim_stat.status == CDSIM_PAUSED && r->cdb[8] & 0x01) {
  3098. X        /* Resume */
  3099. X        cdsim_stat.status = CDSIM_PLAYING;
  3100. X        cdsim_prev_pause += cdsim_pause_elapsed;
  3101. X        cdsim_pause_elapsed = 0;
  3102. X
  3103. X        return(CDSIM_COMPOK);
  3104. X    }
  3105. X    else {
  3106. X        cdsim_stat.status = CDSIM_PAUSED;
  3107. X        time(&cdsim_pause_time);
  3108. X        return(CDSIM_COMPOK);
  3109. X    }
  3110. X}
  3111. X
  3112. X
  3113. X/*
  3114. X * cdsim_m_pause
  3115. X *    Play Audio (12) command simulation function
  3116. X *
  3117. X * Args:
  3118. X *    r - Pointer to the command packet
  3119. X *    s - Pointer to the response packet
  3120. X *
  3121. X * Return:
  3122. X *    Command completion status code
  3123. X */
  3124. X/*ARGSUSED*/
  3125. XSTATIC
  3126. Xcdsim_l_play(simpkt_t *r, simpkt_t *s)
  3127. X{
  3128. X    cdsim_stat.startaddr = (r->cdb[2] << 24) | (r->cdb[3] << 16) |
  3129. X        (r->cdb[4] << 8) | r->cdb[5];
  3130. X    cdsim_stat.endaddr = cdsim_stat.startaddr +
  3131. X        ((r->cdb[6] << 24) | (r->cdb[7] << 16) |
  3132. X         (r->cdb[8] << 8) | r->cdb[9]);
  3133. X
  3134. X    if (cdsim_stat.endaddr <= cdsim_stat.startaddr)
  3135. X        return(CDSIM_PARMERR);
  3136. X
  3137. X    cdsim_start_time = cdsim_now;
  3138. X    cdsim_elapsed = 0;
  3139. X    cdsim_pause_time = 0;
  3140. X    cdsim_pause_elapsed = 0;
  3141. X    cdsim_prev_pause = 0;
  3142. X
  3143. X    cdsim_stat.status = CDSIM_PLAYING;
  3144. X
  3145. X    return(CDSIM_COMPOK);
  3146. X}
  3147. X
  3148. X
  3149. X/*
  3150. X * cdsim_svccmd
  3151. X *    Service a command
  3152. X *
  3153. X * Args:
  3154. X *    r - Pointer to the command packet
  3155. X *    s - Pointer to the response packet
  3156. X *
  3157. X * Return:
  3158. X *    TRUE - success
  3159. X *    FALSE - failure
  3160. X */
  3161. XSTATIC bool_t
  3162. Xcdsim_svccmd(simpkt_t *r, simpkt_t *s)
  3163. X{
  3164. X    memset(s, (byte_t) 0, CDSIM_PKTSZ);
  3165. X
  3166. X#ifdef DEBUG
  3167. X    fprintf(stderr, "cdsim: pktid=%d cdbsz=%d len=%d dir=%d cdb=",
  3168. X        r->pktid, r->cdbsz, r->len, r->dir);
  3169. X
  3170. X    for (i = 0; i < (int) r->cdbsz; i++)
  3171. X        fprintf(stderr, " %02x", r->cdb[i]);
  3172. X
  3173. X    fprintf(stderr, "\n");
  3174. X#endif
  3175. X
  3176. X    /* Set return packet id */
  3177. X    s->pktid = r->pktid;
  3178. X
  3179. X    /* Copy CDB */
  3180. X    s->cdbsz = r->cdbsz;
  3181. X    memcpy(s->cdb, r->cdb, r->cdbsz);
  3182. X
  3183. X    /* Truncate if necessary */
  3184. X    if (s->len > MAX_DATALEN)
  3185. X        s->len = MAX_DATALEN;
  3186. X
  3187. X    /* Direction flag */
  3188. X    s->dir = r->dir;
  3189. X
  3190. X    /* Interpret CDB and service the command */
  3191. X    switch (r->cdb[0]) {
  3192. X    case OP_S_TEST:
  3193. X        /* Test unit ready */
  3194. X        s->retcode = cdsim_s_test(r, s);
  3195. X        break;
  3196. X
  3197. X    case OP_S_INQUIR:
  3198. X        /* Inquiry */
  3199. X        s->retcode = cdsim_s_inquir(r, s);
  3200. X        break;
  3201. X
  3202. X    case OP_S_MSELECT:
  3203. X        /* Mode select */
  3204. X        s->retcode = cdsim_s_mselect(r, s);
  3205. X        break;
  3206. X
  3207. X    case OP_S_MSENSE:
  3208. X        /* Mode sense */
  3209. X        s->retcode = cdsim_s_msense(r, s);
  3210. X        break;
  3211. X
  3212. X    case OP_S_START:
  3213. X        /* Start/stop unit */
  3214. X        s->retcode = cdsim_s_start(r, s);
  3215. X        break;
  3216. X
  3217. X    case OP_S_PREVENT:
  3218. X        /* Prevent/allow medium removal */
  3219. X        s->retcode = cdsim_s_prevent(r, s);
  3220. X        break;
  3221. X
  3222. X    case OP_M_RDSUBQ:
  3223. X        /* Read subchannel */
  3224. X        s->retcode = cdsim_m_rdsubq(r, s);
  3225. X        break;
  3226. X
  3227. X    case OP_M_RDTOC:
  3228. X        /* Read TOC */
  3229. X        s->retcode = cdsim_m_rdtoc(r, s);
  3230. X        break;
  3231. X
  3232. X    case OP_M_PLAY:
  3233. X        /* Play audio (10) */
  3234. X        s->retcode = cdsim_m_play(r, s);
  3235. X        break;
  3236. X
  3237. X    case OP_M_PLAYMSF:
  3238. X        /* Play audio MSF */
  3239. X        s->retcode = cdsim_m_playmsf(r, s);
  3240. X        break;
  3241. X
  3242. X    case OP_M_PLAYTI:
  3243. X        /* Play audio track/index */
  3244. X        s->retcode = cdsim_m_playti(r, s);
  3245. X        break;
  3246. X
  3247. X    case OP_M_PAUSE:
  3248. X        /* Pause/resume */
  3249. X        s->retcode = cdsim_m_pause(r, s);
  3250. X        break;
  3251. X
  3252. X    case OP_L_PLAY:
  3253. X        /* Play audio (12) */
  3254. X        s->retcode = cdsim_l_play(r, s);
  3255. X        break;
  3256. X
  3257. X    default:
  3258. X        /* Command not implemented */
  3259. X        s->retcode = CDSIM_NOTSUPP;
  3260. X        break;
  3261. X    }
  3262. X
  3263. X    return(cdsim_sendpkt("cdsim", cdsim_rfd[1], s));
  3264. X}
  3265. X
  3266. X
  3267. X/*
  3268. X * cdsim_init
  3269. X *    Initialize the CD-simulator subsystem
  3270. X *
  3271. X * Args:
  3272. X *    Nothing.
  3273. X *
  3274. X * Return:
  3275. X *    Nothing.
  3276. X */
  3277. XSTATIC void
  3278. Xcdsim_init(void)
  3279. X{
  3280. X    int        i,
  3281. X            j;
  3282. X    toc_hdr_t    *h1 = (toc_hdr_t *)(void *) cdsim_tocdata1,
  3283. X            *h2 = (toc_hdr_t *)(void *) cdsim_tocdata2;
  3284. X    toc_trk_descr_t    *t1,
  3285. X            *t2;
  3286. X
  3287. X    /* Initialize internal states */
  3288. X    cdsim_stat.status = CDSIM_STOPPED;
  3289. X    cdsim_stat.ntrks = CDSIM_NTRKS;
  3290. X    cdsim_stat.absaddr = 0;
  3291. X    cdsim_stat.reladdr = 0;
  3292. X    cdsim_stat.startaddr = 0;
  3293. X    cdsim_stat.endaddr = 0;
  3294. X    cdsim_stat.caddylock = 0;
  3295. X
  3296. X    /* Addresses for each simulated track and index */
  3297. X    for (i = 0; i < CDSIM_NTRKS; i++) {
  3298. X        if (i == 0)
  3299. X            cdsim_stat.trk[i].addr = 0;
  3300. X        else
  3301. X            cdsim_stat.trk[i].addr = (i * CDSIM_TRKLEN) - 150;
  3302. X
  3303. X        cdsim_stat.trk[i].nidxs = CDSIM_NIDXS;
  3304. X
  3305. X        for (j = 0; j < (int) cdsim_stat.trk[i].nidxs; j++) {
  3306. X            cdsim_stat.trk[i].iaddr[j] = (j * CDSIM_IDXLEN) +
  3307. X                             cdsim_stat.trk[i].addr;
  3308. X        }
  3309. X    }
  3310. X
  3311. X    /* Simulated lead-out track */
  3312. X    cdsim_stat.trk[i].addr = (i * CDSIM_TRKLEN) - 150;
  3313. X    cdsim_stat.trk[i].nidxs = 0;
  3314. X
  3315. X    /* Initialize inquiry data */
  3316. X    cdsim_inqdata.type = DEV_ROM;
  3317. X    cdsim_inqdata.pqual = 0;
  3318. X    cdsim_inqdata.qualif = 0;
  3319. X    cdsim_inqdata.rmb = 1;
  3320. X    cdsim_inqdata.ver = 2;
  3321. X    cdsim_inqdata.len = 38;
  3322. X    strncpy((char *) cdsim_inqdata.vendor, "XMCD    ", 8);
  3323. X    strncpy((char *) cdsim_inqdata.prod, "CD-ROM SIMULATOR", 16);
  3324. X    strncpy((char *) cdsim_inqdata.revnum, CDSIM_VERS, 4);
  3325. X
  3326. X    /* Initialize TOC data */
  3327. X    h1->data_len = h2->data_len = bswap16(
  3328. X        ((CDSIM_NTRKS + 1) * sizeof(toc_trk_descr_t)) + 2
  3329. X    );
  3330. X
  3331. X    h1->first_trk = h2->first_trk = 1;
  3332. X    h1->last_trk = h2->last_trk = CDSIM_NTRKS;
  3333. X
  3334. X    t1 = (toc_trk_descr_t *)(void *) (cdsim_tocdata1 + sizeof(toc_hdr_t));
  3335. X    t2 = (toc_trk_descr_t *)(void *) (cdsim_tocdata2 + sizeof(toc_hdr_t));
  3336. X
  3337. X    for (i = 0; i < CDSIM_NTRKS; i++) {
  3338. X        t1->preemph = t2->preemph = 0;
  3339. X        t1->copyallow = t2->copyallow = 0;
  3340. X        t1->trktype = t2->trktype = 0;
  3341. X        t1->audioch = t2->audioch = 0;
  3342. X        t1->adr = t2->adr = 0;
  3343. X        t1->trkno = t2->trkno = i + 1;
  3344. X        t1->abs_addr.logical = bswap32(cdsim_stat.trk[i].addr);
  3345. X        blktomsf(
  3346. X            cdsim_stat.trk[i].addr,
  3347. X            &t2->abs_addr.msf.min,
  3348. X            &t2->abs_addr.msf.sec,
  3349. X            &t2->abs_addr.msf.frame,
  3350. X            FRAME_PER_SEC << 1
  3351. X        );
  3352. X
  3353. X        t1 = (toc_trk_descr_t *)
  3354. X            ((byte_t *)(void *) t1 + sizeof(toc_trk_descr_t));
  3355. X        t2 = (toc_trk_descr_t *)
  3356. X            ((byte_t *)(void *) t2 + sizeof(toc_trk_descr_t));
  3357. X    }
  3358. X
  3359. X    /* Lead-out track */
  3360. X    t1->preemph = t2->preemph = 0;
  3361. X    t1->copyallow = t2->copyallow = 0;
  3362. X    t1->trktype = t2->trktype = 0;
  3363. X    t1->audioch = t2->audioch = 0;
  3364. X    t1->adr = t2->adr = 0;
  3365. X    t1->trkno = t2->trkno = LEAD_OUT_TRACK;
  3366. X    t1->abs_addr.logical = bswap32(cdsim_stat.trk[i].addr);
  3367. X    blktomsf(
  3368. X        cdsim_stat.trk[i].addr,
  3369. X        &t2->abs_addr.msf.min,
  3370. X        &t2->abs_addr.msf.sec,
  3371. X        &t2->abs_addr.msf.frame,
  3372. X        FRAME_PER_SEC << 1
  3373. X    );
  3374. X}
  3375. X
  3376. X
  3377. X/*
  3378. X * cdsim_main
  3379. X *    The CD simulator main function
  3380. X *
  3381. X * Args:
  3382. X *    Nothing.
  3383. X *
  3384. X * Return:
  3385. X *    Nothing.
  3386. X */
  3387. Xvoid
  3388. Xcdsim_main(void)
  3389. X{
  3390. X    int        i,
  3391. X            j;
  3392. X    simpkt_t    spkt,
  3393. X            rpkt;
  3394. X
  3395. X    fprintf(stderr, "CD-ROM simulator version %s (pid=%d) starting...\n",
  3396. X        CDSIM_VERS, getpid());
  3397. X
  3398. X    /* Install signal handlers */
  3399. X    signal(SIGINT, cdsim_sig);
  3400. X    signal(SIGTERM, cdsim_sig);
  3401. X    signal(SIGHUP, cdsim_sig);
  3402. X
  3403. X    /* Initialize CD-ROM simulator */
  3404. X    cdsim_init();
  3405. X
  3406. X    /* Main simulation service loop */
  3407. X    for (;;) {
  3408. X        /* Get SCSI request */
  3409. X        if (!cdsim_getpkt("cdsim", cdsim_sfd[0], &rpkt))
  3410. X            continue;
  3411. X
  3412. X        time(&cdsim_now);
  3413. X        /* Update status */
  3414. X        switch (cdsim_stat.status) {
  3415. X        case CDSIM_PLAYING:
  3416. X            cdsim_elapsed = cdsim_now - cdsim_start_time -
  3417. X                cdsim_pause_elapsed - cdsim_prev_pause;
  3418. X
  3419. X            cdsim_stat.absaddr = cdsim_elapsed * FRAME_PER_SEC +
  3420. X                cdsim_stat.startaddr;
  3421. X
  3422. X            cdsim_stat.trkno = 0;
  3423. X            for (i = 0; i < (int) cdsim_stat.ntrks; i++) {
  3424. X                if (cdsim_stat.trk[i].addr > cdsim_stat.absaddr)
  3425. X                    break;
  3426. X                cdsim_stat.trkno++;
  3427. X            }
  3428. X
  3429. X            cdsim_stat.idxno = 0;
  3430. X            for (j = 0; j < (int) cdsim_stat.trk[i-1].nidxs; j++) {
  3431. X                if (cdsim_stat.trk[i-1].iaddr[j] >
  3432. X                    cdsim_stat.absaddr)
  3433. X                    break;
  3434. X                cdsim_stat.idxno++;
  3435. X            }
  3436. X
  3437. X            cdsim_stat.reladdr = cdsim_stat.absaddr -
  3438. X                cdsim_stat.trk[i-1].addr;
  3439. X
  3440. X            if (cdsim_stat.absaddr > cdsim_stat.endaddr) {
  3441. X                cdsim_stat.status = CDSIM_STOPPED;
  3442. X                cdsim_elapsed = 0;
  3443. X                cdsim_start_time = 0;
  3444. X                cdsim_pause_time = 0;
  3445. X                cdsim_prev_pause = 0;
  3446. X                cdsim_pause_elapsed = 0;
  3447. X            }
  3448. X            break;
  3449. X
  3450. X        case CDSIM_PAUSED:
  3451. X            cdsim_pause_elapsed = cdsim_now - cdsim_pause_time;
  3452. X            break;
  3453. X        }
  3454. X
  3455. X        /* Process SCSI request */
  3456. X        cdsim_svccmd(&rpkt, &spkt);
  3457. X    }
  3458. X}
  3459. X
  3460. X#else    /* !SIMULATED_CDROM */
  3461. X
  3462. X#ifndef LINT
  3463. Xbool_t                lib_sim = FALSE;
  3464. X#endif
  3465. X
  3466. X#endif    /* SIMULATED_CDROM */
  3467. X
  3468. END_OF_FILE
  3469. if test 18785 -ne `wc -c <'lib_sim.c'`; then
  3470.     echo shar: \"'lib_sim.c'\" unpacked with wrong size!
  3471. fi
  3472. # end of 'lib_sim.c'
  3473. fi
  3474. echo shar: End of archive 8 \(of 13\).
  3475. cp /dev/null ark8isdone
  3476. MISSING=""
  3477. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 ; do
  3478.     if test ! -f ark${I}isdone ; then
  3479.     MISSING="${MISSING} ${I}"
  3480.     fi
  3481. done
  3482. if test "${MISSING}" = "" ; then
  3483.     echo You have unpacked all 13 archives.
  3484.     echo "Now read the README and INSTALL files for further instructions."
  3485.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  3486. else
  3487.     echo You still need to unpack the following archives:
  3488.     echo "        " ${MISSING}
  3489. fi
  3490. ##  End of shell archive.
  3491. exit 0
  3492. -- 
  3493.     ///  Ti Kan                vorsprung durch technik
  3494.    ///   AMB Research Laboratories, Sunnyvale, CA. USA
  3495.   ///    ti@amb.org
  3496.  //////  ...!{decwrl,synopsys,tandem,tsoft,ultra}!sgiblab!bazooka!ti
  3497. ///      ...!uunet!bazooka!ti
  3498.  
  3499.  
  3500.  
  3501. exit 0 # Just in case...
  3502. -- 
  3503.   // chris@Sterling.COM           | Send comp.sources.x submissions to:
  3504. \X/  Amiga: The only way to fly!  |    sources-x@sterling.com
  3505.        "It's intuitively obvious to the most casual observer..."
  3506.  GCS d++(--) -p+ c++ !l u++ e+ m+(-) s++/++ n h--- f+ g+++ w+ t++ r+ y+
  3507.