               ##############################################
               ##############################################
               ##      _   _____           _               ##
               ##     | | |_   _|         | |              ##
               ##     | |   | |  _ __   __| | _____  __    ##
               ##     | |   | | | '_ \ / _` |/ _ \ \/ /    ##
               ##     |_|  _| |_| | | | (_| |  __/>  <     ##
               ##     (_) |_____|_| |_|\__,_|\___/_/\_\    ##
               ##                                          ##
               ##         Comprehensive Disc Indexer       ##
               ##                                          ##
               ##          (c) Stpehen Fryatt; 1995        ##
               ##                                          ##
               ##############################################
               ##############################################
                      
                                Version 1.04
                               (8 April 1996)

                              TECHNICAL DETAILS
                              -----------------


This file contains further details of how Index works internally.  Although
most use for readers who don't mind poking about, it may also be of interest
to those of a not-technical frame of mind who just wish to know slightly more
about Index (and Wimp programming in general :-).  Feel free to poke about
with Index, but remember that if you alter it too much, it may not continue
to work...

   IF YOU DO ALTER INDEX, THEN PLEASE CONTACT ME FOR MY PERMISSION BEFORE
         RELEASING IT EITHER COMMERCIALLY OR INTO THE PUBLIC DOMAIN.

                      THE CODE RETAINS MY COPYRIGHT!

The BASIC code for Index has gone through a BASIC cruncher to reduce its
size: the original was very heavily commented and had long variable names, so
the size was reduced from about 120K to just 35K.  This does not aid the
legibility of the code at all!


File Format
-----------

Index uses its own file format to store indexes.  The file is laid out as
follows, and then compressed using Acorn's Squash application.  The squashed
files are given the Index filetype (&0E1) to distinguish them from normal
squashed files.

Each file begins (before compression) with a standard 40 byte header, as
follows:

Offset   Contents
------   --------
b+0    - Disc name, terminated by a carriage return (&0D).
b+12   - Date of index, in standard Acorn 5-byte format.
b+19   - Index flags (bit 0 indicates small sprites are present).
b+20   - Number of files on disc, 4 bytes.
b+24   - Free space on disc, 4 bytes.
b+28   - Used space on disc, 4 bytes.
b+32   - Format of disc (in Index format).
b+36   - Pointer to icon sprite block, offset from b.
b+40   - First directory block stored here.

After this, the directory data is stored.  The first block is placed at b+40,
and each directory has the following 8 byte header.

Offset   Contents
------   --------
d      - Number of objects in the directory (can be zero).
d+4    - Pointer to parent directory, offset *back* from d.
d+8    - First object's data block here.

Each object has a 44 byte data block, and these are stored sequentially. 
Each data block is as follows:

Offset   Contents
------   --------
n      - File Type.
n+4    - File Name, terminated by a carriage return (&0D).
n+20   - Load address (or Date Stamp).
n+24   - Execution address (or Date Stamp).
n+28   - File Attributes, in standard format.
n+32   - File Size.
n+36   - Sprite Flags (bit 0 indicates the standard sprite exists, 
                       bit 1 indicates the small version exists).
n+40   - Pointer to the sub directory, as an offset from b; or -1.

After the last directory data, the sprites are stored in a standard sprite
area.  Note that the size of the sprite area is set to exactly the correct
size: no more sprites can be added.  This fact is *vital* for some memory
size calculations.

The file is now compressed using Acorn's Squash module.  This begins with the
following header:

Offset   Contents
------   --------
0      - Word containing the ASCII 'SQSH' - This shows a squash file
4      - Original file length (before compression)
8      - Load address of the original file
12     - Exec address of the original file
16     - Flagword: reserved, must be zero
20     - Actual compressed data starts here.

The load routine checks the file for the 'SQSH' header, and uses the original
file length.  The flagword is set to zero, but not checked, and the load and
exec addresses are ignored.  Files saved by versions of !Index less than 1.04
contain undefined values here (whatever was in memory at the time :-), but
versions 1.04 and greater actually set these to zero.  It doesn't actually
matter what values are put here, since they should never be needed, but if it
is possible (if you write your own save routines, perhaps) they should be
zero.


Internal Data
-------------

Each directory viewer on screen has the following data associated with it.

windows%(v,0) - Flag to show windows%(v,i) contains valid data.
windows%(v,1) - Window handle of directory viewer.
windows%(v,2) - Pointer to directory block for viewer.
windows%(v,3) - Pointer to window title for viewer.
windows%(v,4) - Pointer to main block that contains directory block.
windows%(v,5) - Number of columns of icons in viewer.
windows%(v,6) - Display type (1 - Large icons, 2 - Small icons, 3 - Full info)
windows%(v,7) - Position in opening cycle.

This data should never need to ba accessed by the casual user.  Note that the
array windows%() will now have another name due to the BASIC Cruncher.


Memory Allocation
-----------------

All memory claimed by versions 1.04 and on comes from within the Index
WimpSlot.  A fixed 45K heap is used for indirection data within the windows,
and to provide work area for the two Squash_ SWIs.  Space for the
uncompressed files and for indexing comes from a dynamic heap maintained from
BASIC's HIMEM upwards.  Both heaps are managed using OS_Heap.

The dynamic heap tries to grow and shrink as required.  When files are
loaded, if there is not enough free space the WimpSlot is extended, and then
the heap is grown (using OS_Heap 5) to accommodate the new uncompressed file. 
When files are closed, the heap and WimpSlot are shrunk if possible: the heap
suffers from fragmentation in the same way as the RMA, but closing all the
files will restore all the memory!

Versions before 1.04 used the RMA to provide the dynamic heap (the 'easy'
option).  This could cause the RMA to fragment badly, and so the use of these
versions should be avoided.  Also, applications at &8000 should not use
mamory from the RMA (ettiquette, etc...).

The minumum size of the WimpSlot should be about 132K for versions 1.04 up
and about 128K for versions 1.03 down (this will vary depending on your page
size).