
PJB TOC description

A TOC has the following structure:

      Version Record (V)
      Root Record (R)
      Set Record (S)
          Disc Record (D)
                 Track Record (T)       (T, B, I repeated for
		 Track Location (B)	each track on a disc)
		 Track ID (I)
          Disc Record (D)
                 Track Record (T)       (T, B, I repeated for
		 Track Location (B)	each track on a disc)
		 Track ID (I)
      Set Record (S)
          Disc Record (D)
		 ... 
          Disc Record (D)
		 ... 
      ... (additional SET records)
      UID Records (U)
      End of file record (.)
      Allocation map records (+)


typedef struct fs_blkaddr {
    u8 addr[3];
} FS_BLKADDR;

typedef struct fs_allocblock {
	union {
	    struct {
		FS_BLKADDR h_next;            /* Next block in chain */
		FS_BLKADDR h_prev;            /* Previous block in chain */
		u8 userdata[1020];            /* Data not used by player */
		FS_BLKADDR h_next2;           /* Copy of "next block in chain" */
		FS_BLKADDR h_prev2;           /* Copy of "previous block in chain" */
	    } h;
	    u8 head[1032];
	} h;
        u8 body[130032];                      /* Body (mp3 data) */
	union {
	    struct {
		FS_BLKADDR t_next;            /* next block in chain */
		u8 t_chksum[4];               /* checksum of block */
		u8 t_unused;
	    } t;
	    u8 tail[8];
	} t;
} FS_ALLOCBLOCK;


/* (from fs.h & other stuff)

   Conceptual format of an allocation block---these are the parts of the 
   allocation block known to the device.
   A byte_t is a densely packed 8-bit quantity.
        struct fs_allocblock {
                byte_t head[1032];
                byte_t body[130032]
                byte_t tail[8]
        };
   The body is the MP3 data to play.
   The number of the next allocation block to play after this 
   allocation block
   is   head[0]*65536 + head[1]*256 + head[2]
   and  tail[0]*65536 + tail[1]*256 + tail[2]
   where the bytes here are assumed to be unsigned.
   That is, the number is stored twice, once at the start of the
   head, and once at the start of the tail, and in both cases the
   byte order is big-endian.
   The number of the previous allocation block to access on rewind
   is   head[3]*65536 + head[4]*256 + head[5]
   where the bytes here are assumed to be unsigned.
   These numbers are repeated at offset 1026.  That is
           forall i = 1 .. 6: head[1026+i] = head[i]

   The CRC of all bytes in the head, body and the first 3 bytes
   of the tail is stored in tail[4, .., 7].  The bytes should be
   bytes returned by the cksum() call (see the cksum interface).
   
   There is an additional header section that the PC program maintains
   for its own purposes.  The header starts at head[100] and also contains
   the following information (multi-byte quantities are big-endian):
  
	    the header version number (1 byte);
		the content origin (1 byte) ... see AB_Origin_*;
		the track number of the first sample in the block,
			byte value is 255 if not AB_Origin_CD (1 byte);
		the "track offset" (in bytes) from the beginning of buffer of
		   the beginning of a track (if this block contains a beginning of
		   track); -1 otherwise;
		the ordinal block number of this AB within a track,
		   starting at zero (4 bytes);
		the encoding type (1 byte)
		the encoding bit rate (3 bytes)
		the number of bytes in this track in this block  (new as of hdr-version 2)
		the CD-ID of the track's CD (null-terminated string)
		           (AB_Origin_CD only);
		the ID3 tags from an MP3 file (null-terminated string)
		           (AB_Origin_ID3 only);
		a checksum over the entire header (4 bytes)
	
   Header bytes [6..99] are unused.

   Note that for header version = 0, the AB checksum is erroneously computed
   over [0..AB_PayloadSize-4) rather than [0..AB_Size-5).  Also, there is
   no encoding bit rate value or header checksum.

   Note also that as of header version 2, if there are two tracks sharing a
   block, the header refers to the second of the two tracks.  There cannot
   be more than 2 track in a block.
*/


#ifndef _ALLOCBLOCK_H
#define _ALLOCBLOCK_H

#define AB_ClickSize	1024
#define	AB_NClicks		128

#define AB_Size			(AB_ClickSize * AB_NClicks)
#define AB_HeaderSize	(1032) // so that PayloadSize is multiple of 12
#define AB_TrailerSize	(8)
#define	AB_TrailerStart	(AB_Size - AB_TrailerSize)
#define	AB_PayloadStart	(AB_HeaderSize)
#define	AB_PayloadSize	(AB_Size - AB_PayloadStart - AB_TrailerSize)

#define AB_NextLink		0
#define AB_PrevLink		3
#define AB_NextLink1	1026
#define AB_PrevLink1	1029

#define AB_PrivateHdr	(100)
#define AB_HdrVersion	(AB_PrivateHdr)
#define AB_Origin		(AB_PrivateHdr + 1)
#define AB_TrackNumber	(AB_PrivateHdr + 3)
#define AB_TrackOffset	(AB_PrivateHdr + 4)
#define AB_BlockInTrack	(AB_PrivateHdr + 8)
#define AB_Encoding		(AB_PrivateHdr + 12)
#define AB_Bitrate		(AB_PrivateHdr + 13)
#define AB_BytesInBlock	(AB_PrivateHdr + 16)
#define AB_CDID			(AB_PrivateHdr + 60)
#define AB_ID3_TAG		(AB_PrivateHdr + 60)

#define AB_HdrCRC		(1020)  // so that header+CRC can fit in 1024
#define AB_HdrCRCSize	(AB_HdrCRC)  // so that header+CRC can fit in 1024

#define	AB_AltNextLink	(AB_TrailerStart)
#define AB_CRC			(AB_TrailerStart + 4)
#define AB_CRCSize		(AB_AltNextLink + 3)

//#define AB_Origin_CD	(0)		// audio CD capture
//#define AB_Origin_ID3	(1)     // ID3 tagged MP3 file
//#define AB_Origin_Unk	(2)     // untagged MP3 file

#define AB_CURR_HDR_VERSION		(2)
