
------------------------------------------------------------------------------
  TECHNOTE.TXT
  This file is part of the

  PseudoCD package (vesrion 02)
  Copyright (C) C.Kulms, 1997

  This is free software; you can redistribute it and/or modify it
  under the terms of the GNU General Public License as published by
  the Free Software Foundation; version 2 of the License.

  This software is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this software; if not, write to the Free Software
  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
------------------------------------------------------------------------------

PLEASE READ THE FILE 'PSEUDOCD.TXT' FIRST.

While writing the documentation for the PseudoCD package I recognized that
some information, while still being interesting for programmers, is not needed
to just use the software. Inspired by other authors providing a TECHNOTE
I decided to do the same. Remember, if you do not understand the information
given in this file you either failed to understand my English (not unlikely)
or you are not the one supposed to read this (stick to PSEUDOCD.TXT or in case
of trouble discontinue the use of PseudoCD).


CONTENTS

1. Detailed description of the driver functionality
   1.1 Non-existing AUDIO support
   1.2 Other aspects
2. Rebuild the PseudoCD package
3. Information omitted in PSEUDOCD.TXT
   3.1 General usage of PseudoCD drivers
   3.2 The header of an image
   3.3 PSCDDDRV's 'DOS-incompatible' actions
   3.4 The reentrancy problem
   3.5 When is a CDROM device driver called?
   3.6 How to derive an absolute sector number from a given file name
4. Possible future enhancements
   4.1 Image partitions
   4.2 Multi-unit PseudoCD driver
   4.3 Multi-CDROM PseudoCD device
   4.4 Simulated AUDIO support
   4.5 Image consistency checks
5. Literature used


1. DETAILED DESCRIPTION OF THE DRIVER FUNCTIONALITY

As requested by the MSPRM the PseudoCD driver is a character device driver
that supports IOCTL-INPUT, -OUTPUT and OPEN/CLOSE/RM requests. That is it has
the attribute-value 0C800h.

The PseudoCD driver supports only one sub-unit. (More units may be added in a
straight forward way; see 4.2). Only HSG addressing mode is implemented.

The functions defined for CDROM drivers are implemented as follows:

INIT
Reads in the image-header and does some basic checks for validity. If the
initialization fails the driver will be removed entirely. Please see the
source code for details.

IOCTL INPUT

-Return Address of Device Header
 Does exactly this.
 Returns always status 'done'.

-Location of Head
 Reports the internal logged head-location as a HSG-adress.
 Returns always status 'done'.

-Error Statistics
 Not supported (it is unspecified).
 Returns always status 'unknown command'.

-AUDIO channel info
 No AUDIO functions are supported.
 Returns always status 'unknown command'.

-Read Drive Bytes
 This function is ignored - nobody uses it. (Nobody knows this cdrom-drive.)
 Returns always status 'done'.

-Device Status
 Reports the internal logged device-status. Initialised as:
 'closed', 'unlocked', 'cooked only', 'read only', 'no AUDIO play',
 'no interleaving', 'prefetching', 'no AUDIO channel manipulation',
 'hsg-adressing only', 'disk_present', 'no r-w sub-channels'
 Returns always status 'done'.

-Return Volume Size
 Reports the volume size of the original cdrom.
 Returns always status 'done'.

-Media Changed
 Reports always 'media not changed'.
 Returns always status 'done'.

-AUDIO Disk Info
 Reports the data of the original cdrom.
 Returns always status 'done'.

-AUDIO Track Info
 Reports the data of the original cdrom.
 Returns status 'done'.
 If an invalid track-number is given (a number outside of the track-range)
 status 'general failure' is returned. (The MSPRM says nothing about this
 case.)

-AUDIO Q-Channel Info
 No AUDIO functions are supported.
 Returns always status 'unknown command'.

-AUDIO Sub-Channel Info
 No AUDIO functions are supported.
 Returns always status 'unknown command'.

-UPC Code
 Not supported.
 Returns always status 'unknown command'.

-AUDIO Status Info
 No AUDIO functions are supported.
 Returns always status 'unknown command'.

INPUT FLUSH
Does nothing.
Returns always status 'done'.

OUTPUT FLUSH
Not implemented (possible but senseless).
Returns always status 'unknown command'.

IOCTL OUTPUT

-Eject Disk
 Sets device-status 'door open', 'door unlocked', 'no disk present'.
 Returns always status 'done'.

-Lock/Unlock Door
 Sets device-status 'door locked' resp. 'door unlocked'.
 Returns always status 'done'.

-Reset Drive
 Sets device-status 'door closed', 'door unlocked', 'disk present' and resets
 the head-location to sector 0.
 Returns always status 'done'.

-AUDIO Channel Control
 No AUDIO functions are supported.
 Returns always status 'unknown command'.

-Write Device Control String
 This function is ignored - nobody uses it. (Nobody knows this cdrom-drive.)
 Returns always status 'done'.

-Close Tray
 Sets device-status 'door closed', 'disk present' and resets the head-location
 to 0.
 Returns always status 'done'.

DEVICE OPEN
Does nothing.
Returns always status 'done'.

DEVICE CLOSE
Does nothing.
Returns always status 'done'.

READ LONG
Reads the requested cdrom-sectors from the image if possible. Understands
HSG-adressing mode only, 'sector not found' returned if RED-BOOK adress given.
Supports COOKED data read mode only (returns status 'general failure' if RAW
data read mode requested). If the sector-number is invalid it returns status
'sector not found'. Was the read from the image successful status 'done' is
returned, else status 'read fault'. (See also 1.2)

READ LONG PREFETCH
Simply stores the new head-location. Understands HSG-adressing mode only,
'sector not found' returned if RED-BOOK adress given.
Returns status 'done'.

SEEK
Simply stores the new head-location. Understands HSG-adressing mode only,
'sector not found' returned if RED-BOOK adress given.
Returns status 'done'.

PLAY AUDIO
Does nothing. (MSPRM says this request should be ignored if not supported.)
Returns always status 'done'.

STOP AUDIO
Does nothing. (MSPRM says this request should be ignored if not supported.)
Returns always status 'done'.

WRITE LONG
Not implemented (possible but senseless).
Returns always status 'unknown command'.

WRITE LONG VERIFY
Not implemented (possible but senseless).
Returns always status 'unknown command'.

RESUME AUDIO
Does nothing. (MSPRM says this request should be ignored if not supported.)
Returns always status 'done'.

1.1 NON-EXISTING AUDIO SUPPORT

Since a PseudoCD is not a CDROM in a CDROM drive there is no hardware to play
an AUDIO track. It may be possible to play an AUDIO track by a sound card. But
this has to be done in 'background'. Also most CDROMs are not mixed (contain
DATA and AUDIO tracks). If you wish to hear your favourite AUDIO CD simply use
your AUDIO CD-PLAYER. See 4.4 for notes on simulated AUDIO support.

1.2 OTHER ASPECTS

The PseudoCD driver does not use an elaborated security concept: The only
validation for image consistency done is a check for the right header
signature at installation time. If the image is fragmented or corrupted in any
way the driver is not able to detect this. (See also 4.5)

Also the driver handles read-requests in an optimistic way: It tries only once
to read a requested sector - if the hard disk fails, no retry is done. IMHO a
read fault reported by a modern hard disk is serious enough to accept it.

To avoid problems with the 64K segment-limit the driver normalizes the
buffer-pointers. The PseudoCD-driver is able to read more than 64KBytes (32
cd-sectors) at once but this will be save only if the buffer is paragraph
aligned. The applications are fully responsible to respect the restrictions
resulting of the memory segmentation. The MSPRM says nothing about this
problem.


2. REBUILD THE PSEUDOCD PACKAGE

To rebuild the PseudoCD package you need Borland TASM and Borland TC.
Simply use the makefile.

If wish to use a different assembler and/or compiler you have to modify the
source. In general there should be no problems. Some 386er instructions are
used - you may wish to work around them. The code is not optimized anyway -
neither for size nor for speed. Note that the current version of the source is
designed for a 'small memory model', i.e. DS=SS, code and data each have a
maximum of 64KBytes. The functions coded in assembler use far pointers to
avoid any segmentation problems.


3. INFORMATION OMITTED IN PSEUDOCD.TXT

3.1 GENERAL USAGE OF PSEUDOCD DRIVERS

  DEVICE[HIGH]=[full path]PSCDBIOS.SYS /devicename /driveparam /sector

  where

  devicename  name to use (legal 8 character filename)
  driveparam  (drive_number<<16)|(heads<<8)|(sectors_per_track) (hex)
  sector      first absolute sector of the image (hex)
  (Note: 'drive_number' is the number as it is expected by the BIOS)

resp.

  DEVICE[HIGH]=[full path]PSCDDDRV.SYS /devicename /drive /sector

  where

  devicename  name to use (legal 8 character filename)
  drive       MS-DOS drive the image-file resides on (C,D,...)
  sector      first sector of the image relative to the
              beginning of the disk (hex).

resp.

  DEVICE[HIGH]=[full path]PSCDDRIV.SYS /devicename /drive:\path\filename

  where

  devicename      name to use (legal 8 character filename)
  drive           MS-DOS drive the image-file resides on (C,D,...)
  path\filename   path and name of the image file


3.2 THE HEADER OF AN IMAGE

The image header contains information about the CDROM not present in the usual
data sectors of a CDROM: Number and type of the tracks (TOC), volume size,
etc. The user's comment and some additional data is stored there, too. Please
refer to the source (files 'IMAGHEAD.INC', resp. 'IMAGHEAD.H').

3.3 PSCDDDRV'S 'DOS-INCOMPATIBLE' ACTIONS

In the initialization phase the 'DDRV' variant of the PseudoCD driver needs to
call DOS for the Disk Parameter Block (DPB) of the disk the image resides on.
This call is not allowed by the MSPRM at this time. But it seems to work
(there is no reason why it should not - except MS' 'art of coding'). Also the
re-use of a block device drive is neither allowed nor forbidden: The MSPRM
says nothing about this. The re-use of character device drivers is explicitly
noted as a possibility to extend a given device.

It is possible to avoid the above mentioned call by providing the information
needed in the command-line of the PSCDDDRV driver. This will result in
extremly configuration dependent parameters. The current implementation
depends only on the drive-letter. So it is immune against reordering of the
entries in the CONFIG.SYS (which affects the address of the disk driver). Also
adding or removing drives requires the change of only a single letter.

3.4 THE REENTRANCY PROBLEM

This section is not intended to teach you the mysteries of DOS. It is placed
in this document to give you an idea of why there is a problem when an
application reads data from a PseudoCD.

MSCDEX links itself in the network-redirector service interrupt and installs
the CDROM drives as !network! drives: Try a format on a CDROM drive. When an
application wishes e.g. to read a file it launches a read-request to DOS which
in case of a CDROM identifies the drive as a remote one. DOS calls the
network-redirector service to complete the request. At this point MSCDEX
catches the request and builds a corresponding CDROM driver read-request. Then
it calls the CDROM driver and delivers back to DOS whatever the result is (the
requested data or an error code). At last DOS returns to the application the
result of the read operation: For the application this looks like DOS has read
the data from a local drive (by its internal drivers).

A 'real' CDROM driver uses (hardware dependent) port I/O to 'talk' with the
CDROM drive. In case of a PseudoCD device the driver called by MSCDEX has to
access a file on hard disk instead.

Since DOS uses fixed memory locations for system relevant data (and other
crude concepts) most DOS-functions can be used only once at a time. This means
if an application already uses for example the 'read file' service no other
process is allowed to use it until the current is completed. That is what the
term 'reentrancy problem' means.

Therefore the PseudoCD driver has to use routines in a lower layer than the
one DOS provides. There are two possible realizations: Use the BIOS (lowest
hardware independent layer) or use the disk device driver.

There are !undocumented! methods to work around the reentrancy problem without
falling back to low-level services. But these concepts (as any others relying
on undocumented features) are not safe: There is a good chance that they will
fail with other DOS versions. Even complex/highly optimized configurations or
other applications using these features/bugs may cause unforeseen effects.

3.5 WHEN IS A CDROM DEVICE DRIVER CALLED?

MSCDEX calls the driver when it installs the CDROM drives to get the basic
drive abilities (like AUDIO support, prefetch reads, addressing modes). Then
each access to the drive (e.g. read a file) will cause MSCDEX (among other
things) to pass a request to the driver.

The MSCDEX interface allows applications to completely bypass MSCDEX when
accessing the CDROM. So there may be many other situations when the driver
gets called. This is why all the defined CD-!ROM! related functions are
supported by PseudoCD. AUDIO support is not obligate. Refer to 1.1 and 4.4 for
a discussion of AUDIO support.

3.6 HOW TO DERIVE AN ABSOLUTE SECTOR NUMBER FROM A GIVEN FILE NAME

To calculate the absolute sector of a file the file's first cluster number has
to be known. This number is stored in the directory entry for the file. A
directory entry can be get by DOS' !superseeded! 'find first' function (int
21h, function 11h).

The sector number relative to the beginning of the logical drive is derived
from the cluster number by the formula:

 sector = (cluster - 2) * sectors_per_cluster + start_of_data_area

The values 'sectors_per_cluster' and 'start_of_data_area' are stored in the
Disk Paramter Block (DPB; see int 21h, function 32h).

To get an absolute sector number one needs the absolute sector number of the
first sector of the logical drive (i.e. a partition on the hard disk). For
this the Master Partition Records (MPR; also called 'Master Boot Record') of
each BIOS-supported drive have to be read. Then identify the DOS partitions
and walk through eventually present extended partition chains. DOS assigns the
disk letters in the following way:

 The active (primary) partition on the first HDD gets the letter 'C'.

 The other primary partitions get the letters 'D','E',... starting with the
 second HDD.

 At last the extended partitions get their drive letters: Starting with the
 first HDD, walking forward through the Extended Partition Record (EPR) chain,
 then proceeding with the second, third, ... HDD.

(For details on MPR and EPR please refer to the literature/source.)


4. POSSIBLE FUTURE ENHANCEMENTS

This section is a short discussion of possible enhancements to PseudoCD. As
mentioned above this information is mainly addressed to programmers. For
details about the terms/items in this section please refer to the literature.

4.1 IMAGE PARTITIONS

For some reason you might dislike the idea of CDROM images 'floating around'
just like ordinary files. A good idea to avoid this is to use partitions
instead (this will only work with PSCDBIOS.SYS). In fact one of my early
(experimental) versions includes this feature. I decided to ommit it in the
first public version since it does not seem to be very useful in most cases.
Also teaching all the standard users about partitions is tedious. Depending on
feedback I may release the utilities needed.

4.2 MULTI-UNIT PSEUDOCD DRIVER

As mentioned in 1. the PseudoCD driver supports only one unit. To support more
additional intialization code (to load the header data for each image) and
code to handle requests for different units is required. This will increase
the size of the driver significantly. IMHO it is not worth the effort. One can
get additional PseudoCDs by the cost of a small amount of memory: simply load
a second (third,...) instance of the driver.

4.3 MULTI-CDROM PSEUDOCD DEVICE

Since some applications based on more than one compact disk cannot handle
multiple CDROM drives it would be nice to establish a method of changing the
image associated to the PseudoCD driver at run-time (analogous to physically
swapping a CD).

This can be done by a TSR hotkey utility that uses the 'Write Device Control
String' command. But for this a great part of the driver's code which is now
discarded after initialization has to remain in memory.

Another way to realize this feature is to load several PseudoCD drivers and a
dummy driver which is able to redirect a request to the actually selected
PseudoCD: Only the dummy driver had to be installed as a CDROM drive by
MSCDEX. The PseudoCD drivers then could be written as loadable TSRs.

4.4 SIMULATED AUDIO SUPPORT

AUDIO support may be simulated. For a useful subset of functions (PLAY AUDIO,
STOP AUDIO, RESUME AUDIO, and Q-CHANNEL INFO) it is required to extract the
index-data of all tracks from the q-sub-channel at image creation.

This may be done by starting with the indices 1 (stored in the TOC), playing
(short) AUDIO intervalls and monitoring the q-channel to get the red book
addresses of other possible indices.

Also a time-source is needed to simulate the playing process.

If real sound is desired it seems to me the best to design a special (sound
card specific) TSR program which will be called if an PLAY-, STOP-, etc. AUDIO
request is received. It has to read the AUDIO data (by the PseudoCD driver),
prepare it for the sound card, and do all the other stuff needed.

4.5 IMAGE CONSISTENCY CHECKS

As mentioned in 1.2 the current version of the PseudoCD driver is not able to
detect if the CDROM image is fragmented or corrupted. One could easy implement
a 'consistency check' by a table of CRC values for selected CDROM sectors.
They could then be checked at installation or even at runtime. IMHO it is not
worth the effort (and memory): Handle your image files carefully.

4.6 FRAGMENTED IMAGE FILES

The read routine of the PseudoCD driver could be modified to handle 
fragemented image files. That would require less or more complex code that 
'understands' DOS' file-system. IMHO it is not worth the effort; the 
driver would get much slower, too.


5. LITERATURE USED

Microsoft: MS-DOS Programmer's Reference, version 5.0
  Redmond (Washington/USA), 1991
  Microsoft Press, ISBN 1-55615-329-5
  MS Document No. SY0766b-R50-0691

Microsoft: MS-DOS CDROM Extensions Version 2.20 -
  Hardware-Dependent Device Driver Specification
  15 August, 1990
  MS Document No. 000080010-100-O00-1186

Preller, Ralf: Teilen mit System
  in: c't Magazin fr Computer Technik, 10/1988, p.156


ck, 9/Dec/1997

