home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 4 / DATAFILE_PDCD4.iso / utilities / utilsc / computils / !CompUtils / Resources / Expand / Docs next >
Encoding:
Text File  |  1996-03-30  |  28.6 KB  |  624 lines

  1. ############################################################################
  2. #                                                                          #
  3. #                               Expand utility                             #
  4. #                                                                          #
  5. #==========================================================================#
  6. #                                                                          #
  7. #                              by David Radford                            #
  8. #                                                                          #
  9. #==========================================================================#
  10. #                                                                          #
  11. #     These files are a part of !CompUtils and may not be distributed      #
  12. #         separately other than as laid down in the !ReadMe file.          #
  13. #                                                                          #
  14. ############################################################################
  15.  
  16. Overview
  17. ========
  18.  
  19. Expand is a general purpose sample decompressor. There is one piece of code
  20. for each group of sample types supported, plus a 'universal' version that
  21. incorporates all of these. Each version has an identical user interface,
  22. meaning that any program you write can quickly take advantage of new
  23. compression formats provided in future releases of !CompUtils with little
  24. or no changes needed to your code.
  25.  
  26.  
  27. Input/Output
  28. ============
  29.  
  30. The Expand utility passes data to and from it using a pair of buffers. These
  31. must be provided for it by your external program, from hereon referred to as
  32. the master. Data transfers are always controlled by Expand, not the master
  33. program; Expand *requests* new blocks of compressed data from the master,
  34. rather than having them forced upon it. Similarly, Expand *requests* the
  35. master to dispose of data in the output (destination) buffer when it becomes
  36. full.
  37.  
  38. Expand simply treats the input and output buffers as blocks of data. Whether
  39. or not you reuse these areas is up to you (thus making them buffers). If you
  40. prefer, you could load the source sample into one or more blocks of memory
  41. then pass these one at a time to Expand. Obviously these blocks could no
  42. longer be described as buffers. For consistency the term 'buffer' will be
  43. used throughout this document since most uses of Expand will require one or
  44. the other of these blocks to be a buffer.
  45.  
  46.  
  47. The Expand header
  48. =================
  49.  
  50. The code has a standard header through which all parameters are passed:
  51.  
  52.     +0  branch instruction to machine code routine
  53.     +4  filetype for compressed samples
  54.     +8  filetype for sequence files
  55.    +12  pointer to the source buffer (user provided)
  56.    +16  length of source buffer (user provided)
  57.    +20  pointer to the destination buffer (user provided)
  58.    +24  length of destination buffer (user provided)
  59.    +28  number of bytes written into destination buffer
  60.    +32  returned reason code
  61.    +36  output flags (user provided)
  62.    +40  length of final sample
  63.    +44  number of remaining bytes to be written to output
  64.    +48  sample period for output
  65.    +56  file format of source data (eg. 6 for Type 6 samples)
  66.  
  67. Only those entries listed as 'user provided' may be modified; all others are
  68. read-only and provided for information.
  69.  
  70. The source file is decompressed by setting the value at +32 to zero, then
  71. repeatedly calling the location +0 and examining the reason code returned
  72. at +32 to see what action needs to be taken. Typical actions are refilling
  73. the source buffer or outputting the contents of the destination buffer.
  74.  
  75. The master program (ie. the one calling the decompression routine) must
  76. respond to the reason code returned in the way outlined below. There is no
  77. need to call the machine code again immediately, and it may be used quite
  78. happily by repeated calls from the polling loop of a multitasking
  79. application. This is how !Compress works. If you want to do this, then make
  80. sure the buffers are fairly small ie. 16K or so to avoid soaking up too
  81. much processing time.
  82.  
  83. If your program decides to abort the operation for some reason, you MUST
  84. ensure that the reason code is at some stage reset to zero before calling
  85. the machine code routine again (otherwise it will attempt to carry on where
  86. it left off, with disastrous consequences).
  87.  
  88. Note that all source buffers passed, except the last one, must be completely
  89. full. Another way of looking at this is to say that the word at +16 gives
  90. the amount of data actually stored in the source buffer, or that +12 and +16
  91. describe a block of data to be decompressed. Destination buffers will always
  92. be completely full when returned to the master, with the exception of the
  93. very last buffer which may only be partially full (though never completely
  94. empty).
  95.  
  96. When starting a new operation, there is no need to provide a source buffer
  97. until Expand actually asks for one by means of reason code 1. Equally, there
  98. is no need to provide a destination buffer until initialisation is complete
  99. (which you will be informed of via reason code 3).
  100.  
  101.  
  102. The code - Technical details
  103. ============================
  104.  
  105. (Basic and C programmers can ignore all this information.)
  106.  
  107. On entry, R14 contains the return address and R13 must point to a full,
  108. descending stack with space for at least 32 registers. On exit, registers
  109. R0-R12 and R14 will have been corrupted, and the value at +32 will give a
  110. reason code as detailed below. The flags will be corrupted (except for mode
  111. and interrupt), but no SWIs are called so it will operate in any environment
  112. (including machines without a proper operating system). A copy of the reason
  113. code will be returned in R0 to make life easier for you.
  114.  
  115. If you intend to use Expand on an Arm6-based machine (or later) other than
  116. an Acorn computer then you should ensure you are using the 26-bit
  117. programmer's model rather than the 32-bit one, since Expand assumes the
  118. flags and PC are combined into register R15.
  119.  
  120. There is a potential problem when Expand is being used in IRQ mode (or FIQ
  121. mode for that matter) with interrupts enabled, because R14_irq can suddenly
  122. become corrupt. Since R14 is extensively used as a subroutine link register
  123. this can be fairly annoying (and that's putting it mildly!). The solution is
  124. to change the ARM to either to SVC or USR mode before calling Expand.
  125. Obviously this problem only applies when trying to use Expand from interrupt
  126. code, and will not affect programs written in Basic or C.
  127.  
  128.  
  129. Reason codes
  130. ============
  131.  
  132. Below is a description of the meanings of the various reason codes that may
  133. be returned from Expand, together with information on what action should be
  134. taken. In general, reason codes 0-3 are normal operations, 4-7 are 'soft'
  135. errors (from which a sufficiently capable master program can recover without
  136. having to abort the operation), and 8 upwards are 'hard' errors (which must
  137. always cause the operation to abort).
  138.  
  139.  
  140.   0  The operation has now finished.
  141.  
  142.      There is *no* data in the destination buffer, even though the value at
  143.      +28 (the amount of data in the buffer) may be non-zero. In fact, the
  144.      value at +28 is a copy of the value last returned with reason code 2
  145.      *unless* that buffer was completely full in which case +28 is zero.
  146.  
  147.      There is a very good reason for this, though it may not be clear. If
  148.      your program is designed so that it only saves the destination buffer
  149.      on reason code 2 *if* the buffer is completely full, then, on reason
  150.      code 0, the amount of data still to be written is given in +28, and
  151.      the data in the buffer is undamaged. A use for this may seem a little
  152.      obscure, until you consider that the size of the sound system's DMA
  153.      buffers has to be fixed in advance, and decompressing several samples
  154.      in sequence would pose a problem.
  155.  
  156.      After this reason code no more calls to Expand need to be made. Since
  157.      +32 is now set to zero, any future calls would start a *new* operation.
  158.  
  159.  
  160.   1  Source buffer request.
  161.  
  162.      Expand returns this reason code when it wants the master to provide it
  163.      with a new block of source data. You should transfer some data from
  164.      the source file to a convenient block of memory, set +12 to point to it
  165.      and +16 to give the length of it, then call Expand again. Expand treats
  166.      +12 and +16 as read-only fields from its point of view, so you don't
  167.      have to keep resetting these if you are reusing the same block of
  168.      memory. Note that the last buffer does not have to be completely full -
  169.      Expand knows automatically when the end has been reached and ignores
  170.      any further source data.
  171.  
  172.      No copy is made of the data, but copies *are* taken of +12 and +16,
  173.      which makes it impossible to move the source buffer while it is in use.
  174.      Reason code 1 is the only time during an operation where the position
  175.      and size of this buffer can be changed, since it is never in use at
  176.      this point.
  177.  
  178.      No source buffer needs to be provided to Expand until the first time
  179.      reason code 1 is returned. (Before this, +12 and +16 are considered to
  180.      be undefined and can be changed as you see fit.) You can expect this
  181.      event sometime between starting the operation and receiving reason code
  182.      3. Indeed, it's even possible that several buffers would be required
  183.      during the initialisation stage, so no assumptions should be made on
  184.      this count.
  185.  
  186.      By the way, this reason code is *only* for providing a new source
  187.      buffer. You should not attempt to access the destination buffer, and
  188.      the value at +28 will be meaningless. Reason code 2 is used for
  189.      dealing with the destination buffer.
  190.      
  191.      If you find it useful, +44 is preserved from the last time reason
  192.      codes 2 or 3 where returned. However, this value is undefined before
  193.      reason code 3, and since reason code 1 must be returned at least once
  194.      before then this might be a little unreliable.
  195.  
  196.  
  197.   2  The destination buffer has become full.
  198.  
  199.      Expand returns this reason code when it has a block of data for you to
  200.      output. This data is held in the destination buffer, which (with the
  201.      exception of the last block returned) will always be completely full.
  202.      The last buffer returned may be completely full or partially full but
  203.      never completely empty.
  204.  
  205.      Your program should dispose of the data in whatever manner seems fit
  206.      (eg. copy it to disc) then call the expand routine again. If you wish,
  207.      before invoking the routine again your program may also change the
  208.      buffer pointer and length fields at offsets +20 and +24 respectively.
  209.      This is one of the two occasions when you may safely do this; the other
  210.      is on reason code 3 (which is always returned before any attempt is
  211.      made by Expand to access the destination buffer).
  212.  
  213.      The value at +44 (the number of bytes left to be output) will have been
  214.      updated, so you can use this to calculate the percentage done so far
  215.      (eg. for the hourglass). Obviously, the last block to be written will
  216.      be returned with +44 set to zero, a fact you might find useful if you
  217.      are trying to do anything unusual with Expand. However, you should only
  218.      use reason code 0 to terminate the operation.
  219.  
  220.      If you want to calculate the percentage of decompression done, use the
  221.      formula:
  222.  
  223.                             I - C
  224.         Percentage = 100 * -------
  225.                               I
  226.  
  227.      where I is the initial value of the counter (ie. the contents of +40)
  228.      and C is the current value (ie. the contents of +44).
  229.  
  230.      Note that the number of bytes in the destination buffer is given by
  231.      +28. This will usually (but not always) be equal to the value at +24
  232.      (the buffer size). Always use +28 instead.
  233.      
  234.  
  235.   3  Initialisation is complete.
  236.  
  237.      The initial data has been read from the source buffer and various
  238.      variables have been set up. At this point, reason code 1 will has been
  239.      returned at least once, and no attempt has been made to write to the
  240.      destination buffer.
  241.      
  242.      Reason code 3 is also provided as a chance for you to provide some
  243.      initialisation of your own. For example, a destination buffer does
  244.      not need to be set up until this reason code has been returned. And
  245.      the sample period at +48, the output length at +40, and the byte count
  246.      at +44 are only valid from this reason code onwards.
  247.      
  248.      Expand also returns some useful information about the file being
  249.      processed in the output flags word at +36. Once you've started an
  250.      operation, the entire word should be treated as read-only otherwise
  251.      Expand might get confused.
  252.  
  253.      After receiving this reason code (which you will always get, barring
  254.      errors) you may alter the destination buffer pointer and length at
  255.      offsets +20 and +24. The only other times you may alter these values
  256.      are after the utility has finished filling the destination buffer
  257.      (ie. on reason code 2). Note that copies are taken of +20 and +24 so
  258.      it is not possible to move or resize the destination buffer except on
  259.      reason code 2.
  260.  
  261.      The values at offsets +40 and +44 may be useful in determining an
  262.      appropriate size for the destination buffer, or calculating the
  263.      percentage of work done after each call (eg. for the hourglass).
  264.  
  265.      The length at offset +40 is the full length of the sample (in bytes),
  266.      and not the number of actual samples. The distinction is only important
  267.      when outputting 16-bit samples; for 8-bit samples they are the same.
  268.      The value at +44 is used as a counter during the operation. After this
  269.      reason code, +44 will contain its initial value, which is identical to
  270.      +40.
  271.  
  272.      The value at +48 is a single byte given the sample period of the sample
  273.      in microseconds. This information is stored in the file at the time of
  274.      compression, and is otherwise ignored by Expand and Compress, so
  275.      *could* be used to store other information if absolutely necessary.
  276.      (With type 0 samples it must be non-zero.)
  277.  
  278.  
  279.   4  Soft error - undefined
  280.      
  281.      This error is undefined at present. Since it is undefined, it should
  282.      be treated as a hard error for now ie. the operation should be aborted.
  283.      This is only common sense since your program cannot possibly know how
  284.      to correctly recover from this error. It should never occur in code
  285.      from this particular release of !CompUtils. Note that Compress *does*
  286.      have a use for this reason code, and it doesn't consider it to be an
  287.      error either.
  288.  
  289.  
  290.   5  Soft error - source buffer was invalid
  291.  
  292.      This reason code is only returned if there is a bug in your program,
  293.      and should not occur under normal circumstances. It occurs if an
  294.      invalid source buffer was passed after a request for a new source
  295.      buffer (reason code 1). The only check performed on the buffer is that
  296.      the length is not negative and is non-zero.
  297.  
  298.      You should either correct the problem and repeat the call, or abort
  299.      the operation.
  300.  
  301.  
  302.   6  Soft error - destination buffer was invalid
  303.  
  304.      This reason code is only returned if there is a bug in your program,
  305.      and should not occur under normal circumstances. It occurs if an
  306.      invalid destination buffer was passed after a request for a new
  307.      destination buffer (reason code 2). The only check performed on the
  308.      buffer is that the length is not negative and is non-zero.
  309.  
  310.      You should either correct the problem and repeat the call, or abort
  311.      the operation.
  312.  
  313.  
  314.   7  Soft error - undefined
  315.      
  316.      This error is undefined at present. Since it is undefined, it should
  317.      be treated as a hard error for now ie. the operation should be aborted.
  318.      This is only common sense since your program cannot possibly know how
  319.      to correctly recover from this error. It should never occur in code
  320.      from this particular release of !CompUtils.
  321.  
  322.  
  323.   8  Hard error - unknown file format
  324.  
  325.      This reason code is returned if you attempt to decompress a sample
  326.      which uses an algorithm not supported by this particular Expand
  327.      module. If the 'universal' version can't decompress it then it must be
  328.      because you have an out-of-date version of !CompUtils.
  329.  
  330.      This error will most often occur just after the first source buffer
  331.      has been passed to Expand, since that is when the file format is
  332.      checked. It can be returned at other times though, if Expand suddenly
  333.      finds itself unable to cope with something in the compressed data.
  334.      Another common cause of this error is if the source data has been
  335.      corrupted in some way.
  336.  
  337.      There's nothing you can do about this error really (except try to get
  338.      hold of a more up-to-date version of Expand), so you should just abort
  339.      the operation and perhaps display an error message.
  340.  
  341.  
  342. Output flags
  343. ============
  344.  
  345. These control the format of the data written to the output buffer and also
  346. control various options relating to the use of Expand. They are also used
  347. by Expand to pass back certain information you may find useful. The bottom
  348. few bits are provided by use and must be set up before you start calling
  349. Expand. The top few bits are provided by Expand on reason code 3. Once an
  350. operation has been started *none* of the flags should be modified since
  351. Expand may become confused.
  352.  
  353. bit 0 -  If set, this forces the output to be in linear signed format (eg.
  354.          Armadeus format), otherwise it is in logarithmic (VIDC) format
  355.          ready for output to the sound hardware.
  356.  
  357.  
  358. bit 1 -  If set, 2 times oversampling is applied to the output, so it is
  359.          twice the normal length with the extra bytes being formed by
  360.          interpolation. This is useful if the sample was recorded at a very
  361.          low rate, in which case the sampling waveform (which is
  362.          superimposed on the data by the playback hardware) is of a low
  363.          enough frequency to be audible, resulting in a high pitched whining
  364.          sound. Oversampling output goes some way to curing this problem by
  365.          letting you double the sampling frequency.
  366.  
  367.          Note that the sample period returned at +48 in Expand's header is
  368.          not affected by the setting of this bit, and you will have to
  369.          adjust it yourself (by dividing by two).
  370.  
  371.  
  372. bit 2 -  If set, the output is to be stored as 16-bit data, otherwise it
  373.          will be stored as 8-bit. (16-bit data is always stored as
  374.          little-endian ie. lowest byte first.) This bit is ignored if bit 0
  375.          is clear; 16-bit data must always be linear signed since VIDC data
  376.          can only be 8-bit.
  377.         
  378.          Note that not every compression format allows 16-bit data to be
  379.          stored in it. Similarly, not every format allows 8-bit data. Expand
  380.          is able to generate 8-bit data from 16-bit data where necessary
  381.          (with a drop in quality). It can also generate 16-bit data from
  382.          8-bit data, though this is mainly for compatibility since there is
  383.          no advantage in it and it doubles the size of the output.
  384.  
  385.  
  386. bit 28 - (Provided by Expand) If set, Expand intends to store the sample as
  387.          16-bit data, otherwise it will store it as 8-bit data. In certain
  388.          circumstances Expand may be unable to produce the output you
  389.          desire (eg. if you set bit 2 but leave bit 0 clear) so you should
  390.          use this bit to check the output is what you are expecting.
  391.  
  392.  
  393. bit 29 - (Provided by Expand) If set, Expand intends to store the output
  394.          using oversampling. In certain circumstances Expand may be
  395.          unable to produce the output you want so you should use this bit
  396.          to check the output is what you are expecting.
  397.  
  398.  
  399. bit 30 - (Provided by Expand) If set, the data stored in the file is in
  400.          linear signed format, else it is VIDC logarithmic. This is only
  401.          for information since Expand can generate your choice of output.
  402.  
  403.  
  404. bit 31 - (Provided by Expand) If set, the data is stored in the file as
  405.          16-bit samples, otherwise they are 8-bit. There is no point having
  406.          an output resolution greater than that stored in the file, but
  407.          Expand will attempt to generate such output if instructed. This
  408.          bit is provided for information only.
  409.  
  410.  
  411. Filetypes        
  412. =========
  413.  
  414. The filetypes I use for compressed samples and sequence files are:
  415.  
  416.    &350 - Compressed sample
  417.    &351 - Sequence file
  418.  
  419. These filetypes are not Acorn allocated and may change in the future. To
  420. facilitate a smooth transition your program should read the filetypes from
  421. the header on startup. This means that if future versions of Expand use
  422. different filetypes it is a simple matter of replacing the old code with the
  423. new code and everything will still work perfectly (barring renaming the
  424. icons in the !Sprites files).
  425.  
  426.  
  427. File formats
  428. ============
  429.  
  430. You should need to know as little as possible about the contents of a
  431. compressed sample for future compatibility. Most information can be read
  432. from a file by calling Expand until reason code 3 then reading the data from
  433. the header. For more information on the various formats see the !Types file
  434. in the main directory.
  435.  
  436.  
  437. Suggested uses
  438. ==============
  439.  
  440. One possible use of this utility (or one similar to it) is in a game. If the
  441. game consists of a series of levels, there may well be sounds used on some
  442. levels and not on others. On machines with small memories, it makes sense to
  443. store these in a compressed form on disc, and decompress them directly into
  444. memory at the start of any levels that need them.
  445.  
  446. If you do this, you should set up a small source buffer (eg. 1024 bytes)
  447. then call the routine. When reason code 1 is returned you read 1024 bytes
  448. from the file to the source buffer and call Expand again. WHen reason code 3
  449. is returned, the value at offset +40 will be the actual length of the
  450. sample. You can then create a destination buffer of this length, and
  451. repeatedly call the routine again until told to stop, topping up the source
  452. buffer when asked to do so. An example of this is included as a Basic
  453. program called "Example". You will need to alter the variables in$,
  454. out$ and dir$ at the start of the program to get it to run.
  455.  
  456. A second utility called ExpCode is included in !CompUtils in a separate
  457. directory, along with some documentation, and does essentially the same
  458. thing but from machine code. If even ExpCode is too much effort, there's
  459. a module to to it all for you using simple *commands! (See the LoadSample
  460. directory.)
  461.  
  462. If you are writing a game, then why not use the shadow screen memory as the
  463. source buffer, as animation is unlikely to be taking place during
  464. decompression. This saves you having to claim any extra memory for the
  465. source buffer and also gives you a pretty hefty buffer to work with, which
  466. should increase the speed slightly, particularly with floppies.
  467.  
  468. Most of the time Expand converts to the correct output format on the fly, so
  469. the output selected should have little effect on the decompression time. The
  470. exception to this is when both VIDC output and oversampling are enabled,
  471. where the sample is decompressed as oversampled linear then converted to
  472. VIDC when the output buffer is passed back to the user. This is completely
  473. invisible from the outside, but decompression times are slightly higher.
  474. Not all sample Types use this mechanism however - some versions of Expand
  475. can perform *all* the conversions on the fly. Also, the utility may be
  476. slowed down considerably by the screen mode selected unless you are using a
  477. Risc PC with VRAM fitted.
  478.  
  479.  
  480. Using Expand with your own programs
  481. ===================================
  482.  
  483. Basic
  484. -----
  485.  
  486. Choose an appropriate Expand file and copy it into your application's
  487. directory. You can load it using something like this:
  488.  
  489.     SYS "OS_File",5,"<App$Dir>.Expand" TO a%,,,,l%
  490.     IF a%<>1 THEN l%=16
  491.     DIM expand% l%
  492.     SYS "OS_File",255,"<App$Dir>.Expand",expand%,0
  493.  
  494. and the code can be called with:
  495.  
  496.     CALL expand%+0
  497.  
  498. Although Expand returns the reason code in R0, I would not advise using USR
  499. instead of CALL. It's better to use CALL and then read the reason code from
  500. the header. It's easier for debugging for a start.
  501.  
  502.  
  503. Assembler
  504. ---------
  505.  
  506. When including Expand in your own programs there is no reason why it has to
  507. be kept as a separate file in your application's directory. It is actually
  508. designed to be embedded somewhere in the middle of your own code. Refer to
  509. the Technical Details section for more information on calling Expand from
  510. machine code programs.
  511.  
  512.  
  513. ObjAsm
  514. ------
  515.  
  516. Users of Acorn's Desktop Assembler will find an AOF version of Expand in the
  517. 'asm' sub-directory. A header file is provided to IMPORT all the symbols
  518. you'll need. All you have to do is include the line:
  519.  
  520.         GET     CompUtils:Expand.asm.h.Universal
  521.  
  522. at the start of your source code, then add the appropriate object file to
  523. the list of objects and libraries to be linked. There is one object file
  524. for each group of sample types supported (eg. Type0-2, Type6, etc) plus a
  525. 'Universal' version incorporating all of these. Only one header file
  526. is provided (Universal) because the header would be the same for each object
  527. file anyway. By the way, only one Expand object can be linked to your code,
  528. unlike Compress. If you need two or more then use the Universal version.
  529.  
  530. The header file imports symbols for the start of the Expand header (Expand)
  531. and the entry point (Expand_Code). It also defines symbols for offsets from
  532. the start of the header to various entries in the header (eg.
  533. Expand_SrcBufferPtr, Expand_SamplePeriod, etc). So, to read the sample
  534. period you would use something like this:
  535.  
  536.         LDR     R0,=Expand                    ; finds the base address
  537.         LDR     R1,[R0,#Expand_SamplePeriod]  ; reads the word
  538.  
  539. The first instruction transfers the address of Expand's header into R0, then
  540. the second instruction transfers the contents of the sample period entry
  541. into R1. To call Expand use:
  542.  
  543.         BL      Expand_Code
  544.  
  545. which returns a copy of the reason code in R0 to make life easier for you.
  546.  
  547. Apart from these symbols, the header file also defines a series of symbols
  548. for various bits in the output flags eg. OUTPUT_LINEAR, FILE_IS_16BIT, etc.
  549. These should be used in preference to actual values (eg. 1<<2 or 4+2+1)
  550. where possible to allow these to be changed in the future, should the need
  551. arrise. It can also be used to highlight trouble spots, if a bit's meaning
  552. changes.
  553.  
  554. There are also some symbols giving textual equivalents for reason codes
  555. eg. SRC_EMPTY, DEST_FULL, etc which may make your source code easy to read
  556. (unless you're using jump tables of course). Have a look at the header file
  557. for more details.
  558.  
  559.  
  560. C/APCS
  561. ------
  562.  
  563. For C users, a header file and a series of object files can be been found
  564. in the 'cc' sub-directory. Only one header file is provided (Universal)
  565. because all the decompressors have an identical user interface, so the
  566. Universal version can be used for any of them. An object file is provided
  567. for each group of sample types (eg. Type0-2, Type6, etc) plus a Universal
  568. version combining all of these. Only one of these object files can be linked
  569. with your code; if you want more than one then use the Universal version
  570. instead.
  571.  
  572. The object code is APCS-compliant (obviously) so can be used from any APCS
  573. language, such as Pascal, C++, etc. You would have to write your own header
  574. file though - the one provided is for C, and should be included in your
  575. source with:
  576.  
  577. #include "CompUtils:Expand.cc.h.Universal"
  578.  
  579. It defines the entries in Expand's header as global variables that can be
  580. accessed just like normal variables eg.
  581.  
  582.         int     filetype;
  583.         int     count;
  584.         char    *buffer;
  585.         char    bytes[16];
  586.         
  587.         filetype = Expand_SampleType;
  588.         buffer = Expand_DestBufferPtr;
  589.         for (count = 0; count < 16; count++)
  590.             bytes[count] = buffer[count];
  591.         
  592. Apart from these variables, the header file also defines a series of symbols
  593. for various bits in the output flags eg. OUTPUT_LINEAR, FILE_IS_16BIT, etc.
  594. These should be used in preference to actual values (eg. 1<<2 or 4+2+1)
  595. where possible to allow these to be changed in the future, should the need
  596. arrise. It can also be used to highlight trouble spots: if a bit's meaning
  597. changes then so would the name attached to it, and the compiler would spot
  598. the fact that the symbol no longer exists.
  599.  
  600. There are also some symbols giving textual equivalents for reason codes
  601. eg. SRC_EMPTY, DEST_FULL, etc which may make your source code easy to read,
  602. especially when using 'switch'. Have a look at the header file for more
  603. details.
  604.  
  605. To call Expand just make a call to function Expand(). This takes no
  606. arguments and returns the reason code (which is also held in global variable
  607. Expand_ReasonCode). Please look at the example file provided for further
  608. details.
  609.  
  610.  
  611. Bugs
  612. ====
  613.  
  614. There may well be some bugs lurking around, particularly in the ObjAsm and C
  615. versions of Expand (I never use these myself). They have been tested with
  616. the example programs so they should work, but you never know. Please report
  617. any bugs, omissions or suggestions for improvement to one of the addresses
  618. in the main !ReadMe file.
  619.  
  620.  
  621.                            (c) David Radford
  622.  
  623.  
  624.