#
# @(#)PORTING	2.12 94/02/16
#
Xmcd (Motif(tm) CD Audio Player) by Ti Kan
------------------------------------------

Porting Information
-------------------


INTRODUCTION

A truly portable program should compile and run without modification
on different OS and hardware platforms.  Any CD Audio player software,
especially under UNIX, is typically not very portable.  This is because
of the two following reasons:

    1. Different OS implementations provide different means
       of operating the CD-ROM drives.
    2. Although there is an increasing number of CD-ROM drives
       that implement the audio-related commands as documented
       in the SCSI-2 specifications, many non-SCSI-2 conformant
       CD-ROM drives exist, and support audio operations only
       via incompatible vendor-unique commands.  Moreover, there
       are also a number of non-SCSI CD-ROM drives that operate
       via proprietary controller boards.

Xmcd strives to be as portable as possible by taking the following
design approach:

    1. Harness the inherent portability advantages of the X Window
       System, and the increasing popularity of the OSF/Motif GUI.
       The X Window System gives us device-independent graphics
       and network-extensibility, and Motif is rapidly becoming
       the de facto standard UNIX GUI, and will soon be supported
       on virtually every vendor's port of UNIX as well as UNIX-like
       operating systems.
    2. Strict adherence to ANSI C standards.
    3. Modularize the internals of xmcd, such that the user interface
       portion, the OS-interface portion, and the CD-ROM vendor-unique
       support portions are each a separate and replaceable entity.
    4. The OS-specific and device-specific portions are made as small
       and self-contained as possible, so that changes to support
       a new OS or new CD-ROM drive are not scattered about.

Currently xmcd already supports a wide array of SCSI CD-ROM drives
and several OS environments.  However, the more devices xmcd
supports, and the more OS environments it runs under, the better.
To that end, I encourage you to contribute to xmcd and make it
a better program.  If you would like to add support of additional
CD-ROM devices, port xmcd to run on another OS, or to add other
enhancements to xmcd, the xmcd internal architecture overview below
should prove to be beneficial.

Xmcd currently contains code that assumes a POSIX-compliant UNIX
C library and headers, and certain System V characteristics.
Examples of these are:

	- Uses "struct dirent" rather than "struct direct"
	- Assumes existence of types such as "uid_t" and "mode_t".
	- etc...

Although xmcd has been ported to run on SunOS (The SunOS 4.x
environment is BSD-like), you may need to make certain modifications
to port xmcd to other BSD-derived or BSD-like environments.

Please note that xmcd is released as free software under the GNU
General License Agreement, which guarantees your right to modify
xmcd for yourself and others (please see the COPYING file for
details).  I do ask, however, that if you add new functionality
to xmcd or port xmcd to a new platform, please send all changes to
me so I can merge it into the main source code and include it in
the next release.  All proper credit will be given, of course,
in the form of Copyright notices in the source file banners.
This avoids diverging versions and makes your enhancements accessible
to more people.



XMCD ARCHITECTURE

Xmcd is divided into two main subsystems, the Application Code
Subsystem and the Device Interface Subsystem (These are hereafter
referred to as ACS and DIS, respectively).

The diagram below shows the general xmcd architecture, and
identifies where the various libraries (Motif, Xt, X11, socket,
and the C library) interface with the main xmcd bodies of code.


		    General Xmcd Internal Architecture
		    ----------------------------------

                              User Interface
  +-------------------------------------------------------------------------+
  |                                                                         |
  |                          Motif                                          |
  |                                                                         |
  |   +----------------+----------------------------------------------------+
  |   |                |                                                    |
  |   |  Xt            |       Xmcd Application Code Subsystem (ACS)        |
  |   |  Intrinsics    |                                                    |
  |   |                |             +--------------------------------------+
  |   |                |             |                                      |
  |   |   +------------+             |                                      |
  |   |   |            |             |                                      |
  |   |   |  X11       |             |   Xmcd Device Interface Subsystem    |
  |   |   |            |             |   (DIS)                              |
  |   |   |   +--------+             |                                      |
  |   |   |   |        |             |                                      |
  |   |   |   | socket |             |                                      |
  |   |   |   |        |             |                                      |
  +---+---+---+--------+-------------+--------------------------------------+
  |                                                                         |
  |                  C Library / System Calls                               |
  |                                                                         |
  +-------------------------------------------------------------------------+
                                OS Kernel



The ACS is the layer that deals with the user interface and mostly
uses Motif for that purpose.  It provides the look-and-feel of the
application and manages all user events.  The ACS also provides a set
of general service functions for the DIS to call.  There are two
general classes of these functions.  The first of these are functions
that cause changes on the user interface (display popup messages,
change widget state, etc.), and the second are general service routines
(perform byte-swapping, BCD to integer conversion, etc).  This layer
is hardware platform and OS independent and should require virtually
no modifications to port to other environments.

The DIS can be hardware and OS dependent.  The interface from the
ACS layer to the DIS is very high-level, consisting of function
calls like di_playpause(), di_stop(), di_rew(), di_ff(),
and so on (see di_lib.h for the full list).  This gives the DIS a lot
of flexibility in how to implement the actual functionalities.
Furthermore, the DIS physically resides in a library archive.
Although it is currently linked into xmcd statically, if the need
arises it can be modified to be dynamically bound.

The DIS module that is supplied with this version of xmcd implements
a SCSI pass-through command interface which supports many OS
environments and CD-ROM drive types.  This is described in the next
section.



SCSI PASS-THROUGH DEVICE INTERFACE SUBSYSTEM

The SCSI pass-through DIS supplied is a conglomerate of a Generic
SCSI pass-through module, an OS Interface module, and several
Vendor-unique modules (see diagram below).  This DIS implements all
the non-user-interface aspects of CD audio functionality and operates
the CD-ROM drive by delivering SCSI commands directly to the CD-ROM
drive via a kernel-supported SCSI pass-through interface.

Xmcd currently supplies several OS Interface Modules, each supporting
a different operating system platform; as well as a "demo" module
that provides a demo environment, but does not actually operate a
real CD-ROM drive (a CD-ROM simulator is invoked instead, mimicking
the behavior of a CD-ROM drive).  Xmcd also supplies several vendor-
unique modules for Chinon, Hitachi, NEC, Pioneer, Sony and Toshiba
CD-ROM drives.  Only one OS Interface module can be compiled in at a
time (controlled by pre-processor directives), but multiple vendor-
unique modules can coexist.

Xmcd currently supports various flavors of UNIX SVR4, SunOS, SCO ODT,
HP-UX, SGI Irix, DEC Ultrix, DEC OSF/1, IBM AIX and Linux via the
SCSI pass-through DIS.


			SCSI Pass-through DIS Detail
			----------------------------

                              User Interface
  +-------------------------------------------------------------------------+
  |                                                                         |
  |                          Motif                                          |
  |                                                                         |
  |   +----------------+----------------------------------------------------+
  |   |                |                                                    |
  |   |  Xt            |       Xmcd Application Code Subsystem (ACS)        |
  |   |  Intrinsics    |                                                    |
  |   |                |          +-----------------------------------------+
  |   |                |          |                                         |
  |   |   +------------+          |     Generic SCSI Pass-through           |
  |   |   |            |          |     Library Module                      |
  |   |   |  X11       |          |                                         |
  |   |   |            |          |    +-----------------+------------------+
  |   |   |   +--------+          |    |                 | Vendor-unique    |
  |   |   |   |        |          |    | OS Interface    | Library Modules  |
  |   |   |   | socket |          |    | Library Modules +------------------+
  |   |   |   |        |          |    |                                    |
  +---+---+---+--------+----------+----+------------------------------------+
  |                                                                         |
  |                  C Library / System Calls                               |
  |                                                                         |
  +-------------------------------------------------------------------------+
                                OS Kernel



XMCD SOURCE CODE FILES

The following is a list of the files in the xmcd source code
distribution and the category they fall under.  Note that the
file name prefix for C source and header files generally illustrates
the module category:

General files:

	BUGS
	COPYING
	CHANGES
	INSTALL
	PORTING
	README
	Imakefile
	XMcd.ad
	cfgtbl/*
	demo.cddb
	dev.config
	install.sh
	configure.sh
	makerel.sh
	makesrc.sh
	xmcd.man

ACS files:

	xmcd.h
	patchlevel.h
	bitmaps/*.xbm
	helpfiles/*
	ac_resrc.h
	ac_main.c
	ac_cdfunc.[ch]
	ac_dbprog.[ch]
	ac_geom.[ch]
	ac_help.[ch]
	ac_hotkey.[ch]
	ac_util.[ch]
	ac_widget.[ch]

DIS files:

	di_lib.h

	SCSI Pass-through module:

	    di_scsipt.[ch]

		OS Interface modules:

		    os_demo.[ch] and os_cdsim.[ch]
		    os_aix.[ch]
		    os_dec.[ch]
		    os_hpux.[ch]
		    os_irix.[ch]
		    os_linux.[ch]
		    os_odt.[ch]
		    os_sun.[ch]
		    os_svr4.[ch]

		Vendor-unique support modules:

		    vu_hita.[ch]
		    vu_nec.[ch]
		    vu_pion.[ch]
		    vu_sony.[ch]
		    vu_tosh.[ch]



SCSI PASS-THROUGH DIS vs. MONOLITHIC DIS

On a kernel that does not supports SCSI pass-through, but otherwise
implements a different interface to the CD-ROM drive, another
monolithic module similar to the SCSI pass-through DIS can be developed
to interface with the CD-ROM device.  Similarly, if xmcd were to be
expanded to support non-SCSI CD-ROM drives, a different DIS can be
written to interface with the appropriate device driver.

If the OS kernel has a SCSI pass-through interface (and most UNIX
OS flavors today do), it is desirable and easier to port xmcd by
writing a new OS Interface layer.  This involves much less code than
a whole DIS module, not to mention the benefit of a much wider range
of CD-ROM device support.

In the supplied SCSI pass-though DIS, the Generic SCSI pass-through
portion contains all the basic non-OS-dependent portion of the code
that implements delivering SCSI commands to a CD-ROM drive.  It relies
on the next layer, the OS Interface layer, to actually perform the SCSI
command delivery.  The SCSI pass-through module "knows" about the
SCSI-2 set of audio-related commands, and sends these down to the OS
Interface layer.  Which SCSI-2 commands to send are user-configurable
via device-dependent configuration files.  This is important because
many CD-ROM drives support some, but not all of the SCSI-2 audio
commands.  Alternatively, if so configured, the SCSI Pass-through
module can call the Vendor-unique module to deliver non-SCSI-2
vendor-unique commands to the CD-ROM drive.

All entry points to the OS Interface module are named in the
form of pthru_xxx().  See os_svr4.h, os_odt.h, os_sun.h, etc.
for a full list.

The most important OS Interface module entry point is pthru_send(),
which is used by the SCSI Pass-through and Vendor-unique modules
to deliver SCSI commands to the drive.  pthru_send() takes
a number of arguments that are used to construct a SCSI CDB,
among other things.  The SCSI CDB is actually allocated and
filled in the OS Interface module, and delivered using the
appropriate SCSI pass-through mechanism.



PORTING HINTS

To port xmcd to a different OS, two alternatives can be
considered:

1. Use the existing SCSI pass-through DIS, but write a new
   OS Interface module.
2. Write a whole new monolithic DIS.

The first choice is the obvious answer if the target OS supports a
SCSI pass-through interface.  This choice is also quite easy to
implement, as the OS Interface module is typically fairly small
and self-contained.  The existing OS Interface modules can be used
as a reference when writing a new one.  In the current implementation,
each SCSI pass-through OS Interface module must contains these three
routines:

	pthru_send()
	pthru_open()
	pthru_close()

The second choice is feasible if the OS does not supply a SCSI
pass-through mechanism, or if non-SCSI drives are to be used.
If this is the approach taken, the SCSI pass-through DIS
source can be used as a reference, and much of its code can be
copied, modified and re-used.

If you are writing an OS Interface module, keep in mind that you
will need to deal with any special DMA address alignment limitations
present in your OS and/or hardware.  The I/O data buffers allocated
within the existing SCSI pass-through DIS is guaranteed to be
32-bit word-aligned, but if your OS/hardware has different
requirements (such as page-alignment) then you will need to
deal with this in the OS interface module.

Remember the issue of big vs. small endian?  Please use the
bswapxx() and lswapxx() routines provided in ac_util.c
(#include "ac_util.h") to perform byte swapping.  This is necessary
because multi-byte quantities in SCSI commands and data is in general
big-endian, but xmcd is designed to run on host CPUs that are
big-endian or little-endian.  The swap routines should be used
regarless of whether your main CPU endianess matches that of the
SCSI device.  Whether swapping actually takes place is controlled
via the _BYTE_ORDER_ #define (see xmcd.h).

There are also some minor OS-specific code you need to add in
configure.sh.  This is mainly to set up the correct default device
node path name.


ADDING SUPPORT OF NON-SCSI-2 CD-ROMS

To support additional SCSI (not SCSI-2) CD-ROM drives via vendor-
unique pass-through commands, you will need to add a vendor-unique
module to xmcd.  Each vendor-unique module can implement some or all
of the following routines (where xx is the name of the vendor-unique
module):

	xx_playaudio()
	xx_pause_resume()
	xx_start_stop()
	xx_get_playstatus()
	xx_volume()
	xx_mute()
	xx_get_toc()
	xx_eject()
	xx_start()
	xx_halt()

These routines, if implemented, is then registered in the xx_init()
routine by filling in the appropriate vu_tbl_t array entry (see
di_scsipt.h and the existing vendor-unique modules for examples).

Depending upon the operating mode of xmcd, vendor-unique functionality
is invoked from the di_scsipt.c module via the vu_tbl_t jump table.

In addition to writing the new vendor-unique module, you
will also need to make a few minor additions to di_scsipt.c and
di_scsipt.h.  Look for #ifdef TOSHIBA, #ifdef NEC, etc., in these
files for examples.

You will also need to add a vendor-unique configuration file entry 
to the cfgtbl subdirectory.



QUESTIONS?

If you are working on enhancing xmcd and need information, help
or advice, please send e-mail to me at "ti@amb.org".  Likewise,
suggestions are also very welcome.


