formats index
	*** G64 (raw GCR binary representation of a 1541 diskette)

** Document revision 1.1

  This format was defined in 1998 as a cooperative effort  between  several
emulator people,  mainly  Per  Hakan  Sundell,  author  of  the  CCS64  C64
emulator, Andreas Boose of the VICE CBM emulator team and Joe  Forster/STA,
the author of Star Commander. It was  the  first  real  public  attempt  to
create a format for the emulator community which removed almost all of  the
drawbacks of the other existing image formats, namely D64.

  The intention behind G64 is not to replace the widely used D64 format, as
D64 works fine with the vast majority of disks in existence. It is intended
for those small percentage of programs which demand to work with  the  1541
drive in a non-standard way, such as reading or writing data  in  a  custom
format. The best example is with speeder software such as Action  Cartridge
in "warp save" mode or Vorpal which  write  track/sector  data  in  another
format other than standard GCR. The other obvious example is copy-protected
software which looks for some specific data on a track, like the  disk  ID,
which is not stored in a standard D64 image.

  G64 has a deceptively simply layout for what it is capable of  doing.  We
have a signature, version byte, some predefined size values, and  a  series
of offsets to the track data and speed zones. It is what's contained in the
track data areas and speed zones which is  really  at  the  heart  of  this
format.

  Each track data area is simply the raw stream of GCR data, just what  the
read head would see when a diskette is rotating past it. How the data  gets
interpreted is up to the program trying to access  the  disk.  Because  the
data is stored in such a low-level manner, just about anything can be done.
Most of the time I would suspect the data in the track  would  be  standard
sectors, with SYNC, GAP, header, data and checksums. The arrangement of the
data when it is in a standard GCR sector layout is covered in a  small  way
at the end of this document.

  Since it is a flexible format in both track count and  track  byte  size,
there is no "standard" file size. However, given a few  constants  like  42
tracks and halftracks, a track size of  7928  bytes  and  no  speed  offset
entries, the typical file size will a minimum of 333744 bytes.

  Below is a dump of the header, broken down into its various parts.  After
that will be an explanation of the  track  offset  and  speed  zone  offset
areas, as they demand much more explanation.


Addr  00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F        ASCII
----  -----------------------------------------------   ----------------
0000: 47 43 52 2D 31 35 34 31 00 54 F8 1E .. .. .. ..   GCR-1541T....

  Bytes: $0000-0007: File signature "GCR-1541"
               0008: G64 version (presently only $00 defined)
               0009: Number of tracks in image (usually $54, decimal 84)
          000A-000B: Size of each stored track in bytes (usually  7928,  or
                     $1EF8 in LO/HI format.

  An obvious question here is "why are  there  84  tracks  defined  when  a
normal D64 disk only has 35 tracks?" By  definition,  this  image  includes
*all* the tracks that a real 1541 can access, which is  42  tracks  and  42
half tracks. Even though using more than 35 tracks is not typical,  it  was
important to define this format from  the  start  with  what  the  1541  is
capable of doing, and not just what it typically does.

  At first, the defined track size value of  7928  bytes  may  seem  to  be
arbitrary, but it is not. It is  determined  by  the  fastest  write  speed
possible (speed zone 0), coupled with the average  rotation  speed  of  the
disk (300 rpm). After some math, the answer that actually comes up is  7692
bytes. Why the discrepency between the actual size of 7692 and the  defined
size of 7928? Simply put, not all drives rotate at 300  rpm.  Some  can  be
faster or slower, so a upper safety margin of +3% was built added, in  case
some disks rotate slower and can  write  more  data.  After  applying  this
safety factor, and some rounding-up, 7928 bytes per track was arrived at.

  Also note that this upper limit of  7928  bytes  per  track  really  only
applies to 1541 (and compatible) disks. If  this  format  were  applied  to
another disk type like the SFD1001, this value would be higher.

  Below is a dump of the first section of a G64 file, showing  the  offsets
to the data portion for each track and half-track entry. Following that  is
a dump of the speed zone offsets.

Addr  00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F        ASCII
----  -----------------------------------------------   ----------------
0000: .. .. .. .. .. .. .. .. .. .. .. .. AC 02 00 00   ............
0010: 00 00 00 00 A6 21 00 00 00 00 00 00 A0 40 00 00   !@
0020: 00 00 00 00 9A 5F 00 00 00 00 00 00 94 7E 00 00   _~
0030: 00 00 00 00 8E 9D 00 00 00 00 00 00 88 BC 00 00   
0040: 00 00 00 00 82 DB 00 00 00 00 00 00 7C FA 00 00   |
0050: 00 00 00 00 76 19 01 00 00 00 00 00 70 38 01 00   vp8
0060: 00 00 00 00 6A 57 01 00 00 00 00 00 64 76 01 00   jWdv
0070: 00 00 00 00 5E 95 01 00 00 00 00 00 58 B4 01 00   ^X
0080: 00 00 00 00 52 D3 01 00 00 00 00 00 4C F2 01 00   RL
0090: 00 00 00 00 46 11 02 00 00 00 00 00 40 30 02 00   F@0
00A0: 00 00 00 00 3A 4F 02 00 00 00 00 00 34 6E 02 00   :O4n
00B0: 00 00 00 00 2E 8D 02 00 00 00 00 00 28 AC 02 00   .(
00C0: 00 00 00 00 22 CB 02 00 00 00 00 00 1C EA 02 00   "
00D0: 00 00 00 00 16 09 03 00 00 00 00 00 10 28 03 00   (
00E0: 00 00 00 00 0A 47 03 00 00 00 00 00 04 66 03 00   Gf
00F0: 00 00 00 00 FE 84 03 00 00 00 00 00 F8 A3 03 00   
0100: 00 00 00 00 F2 C2 03 00 00 00 00 00 EC E1 03 00   
0110: 00 00 00 00 E6 00 04 00 00 00 00 00 E0 1F 04 00   
0120: 00 00 00 00 DA 3E 04 00 00 00 00 00 D4 5D 04 00   >]
0130: 00 00 00 00 CE 7C 04 00 00 00 00 00 C8 9B 04 00   |ț
0140: 00 00 00 00 C2 BA 04 00 00 00 00 00 BC D9 04 00   º
0150: 00 00 00 00 B6 F8 04 00 00 00 00 00 .. .. .. ..   .....

  Bytes: $000C-000F: Offset  to  stored  track  1.0  ($000002AC,  in  LO/HI
                     format, see below for more)
          0010-0013: Offset to stored track 1.5 ($00000000)
          0014-0017: Offset to stored track 2.0 ($000021A6)
             ...
          0154-0157: Offset to stored track 42.0 ($0004F8B6)
          0158-015B: Offset to stored track 42.5 ($00000000)


      00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F        ASCII
      -----------------------------------------------   ----------------
0150: .. .. .. .. .. .. .. .. .. .. .. .. 03 00 00 00   ............
0160: 00 00 00 00 03 00 00 00 00 00 00 00 03 00 00 00   
0170: 00 00 00 00 03 00 00 00 00 00 00 00 03 00 00 00   
0180: 00 00 00 00 03 00 00 00 00 00 00 00 03 00 00 00   
0190: 00 00 00 00 03 00 00 00 00 00 00 00 03 00 00 00   
01A0: 00 00 00 00 03 00 00 00 00 00 00 00 03 00 00 00   
01B0: 00 00 00 00 03 00 00 00 00 00 00 00 03 00 00 00   
01C0: 00 00 00 00 03 00 00 00 00 00 00 00 03 00 00 00   
01D0: 00 00 00 00 03 00 00 00 00 00 00 00 03 00 00 00   
01E0: 00 00 00 00 02 00 00 00 00 00 00 00 02 00 00 00   
01F0: 00 00 00 00 02 00 00 00 00 00 00 00 02 00 00 00   
0200: 00 00 00 00 02 00 00 00 00 00 00 00 02 00 00 00   
0210: 00 00 00 00 02 00 00 00 00 00 00 00 01 00 00 00   
0220: 00 00 00 00 01 00 00 00 00 00 00 00 01 00 00 00   
0230: 00 00 00 00 01 00 00 00 00 00 00 00 01 00 00 00   
0240: 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00   
0250: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   
0260: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   
0270: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   
0280: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   
0290: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   
02A0: 00 00 00 00 00 00 00 00 00 00 00 00 .. .. .. ..   ....

  Bytes: $015C-015F: Speed zone entry for track 1 ($03,  in  LO/HI  format,
                     see below for more)
          0160-0163: Speed zone entry for track 1.5 ($03)
             ...
          02A4-02A7: Speed zone entry for track 42 ($00)
          02A8-02AB: Speed zone entry for track 42.5 ($00)

  Starting here at $02AC is the first track entry (from above,  it  is  the
first entry for track 1.0)

  The track offsets (from above) require some explanation. When one is  set
to all 0's, no track data exists for this entry. If there is a value, it is
an absolute reference into the file (starting from  the  beginning  of  the
file). From the track 1.0 entry we see it is set for  $000002AC.  Going  to
that file offset, here is what we see...

      00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F        ASCII
      -----------------------------------------------   ----------------
02A0: .. .. .. .. .. .. .. .. .. .. .. .. 0C 1E FF FF   ............
02B0: FF FF FF 52 54 B5 29 4B 7A 5E 95 55 55 55 55 55   RT)Kz^UUUUU
02C0: 55 55 55 55 55 55 FF FF FF FF FF 55 D4 A5 29 4A   UUUUUUUԥ)J
02D0: 52 94 A5 29 4A 52 94 A5 29 4A 52 94 A5 29 4A 52   R)JR)JR)JR

  Bytes: $02AC-02AD: Actual size of stored track (7692 or $1E0C,  in  LO/HI
                     format)
          02AE-02AE+$1E0C: Track data

  Following the track data is filler bytes. In this  case,  there  are  368
bytes of unused space. This space can contain anything, but for the sake of
those wishing to compress these images for storage, they should all be  set
to the same value. In the sample I used, these are all set to $FF.

  Below is a dump of the end of the track 1.0 data area.  Note  the  actual
track data ends at address $20B9, with the rest of the block being  unused,
and set to $FF.

      00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F        ASCII
      -----------------------------------------------   ----------------
1FE0: 52 94 A5 29 4A 52 94 A5 29 4A 52 94 A5 29 4A 52   R)JR)JR)JR
1FF0: 94 A5 29 4A 52 94 A5 29 4A 52 94 A5 29 4A 52 94   )JR)JR)JR
2000: A5 29 4A 52 94 A5 29 4A 52 94 A5 29 4A 52 94 A5   )JR)JR)JR
2010: 29 4A 52 94 A5 29 4A 52 94 A5 29 4A 52 94 A5 29   )JR)JR)JR)
2020: 4A 52 94 A5 29 4A 52 94 A5 29 4A 52 94 A5 29 4A   JR)JR)JR)J
2030: 55 55 55 55 55 55 FF FF FF FF FF FF FF FF FF FF   UUUUUU
2040: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF   
2050: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF   
2060: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF   
2070: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF   
2080: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF   
2090: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF   
20A0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF   
20B0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF   
20C0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF   
20D0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF   
20E0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF   
20F0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF   
2100: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF   
2110: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF   
2120: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF   
2130: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF   
2140: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF   
2150: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF   
2160: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF   
2170: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF   
2180: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF   
2190: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF   
21A0: FF FF FF FF FF FF .. .. .. .. .. .. .. .. .. ..   ..........

  The speed offset entries can be a little more complex. The 1541 has  four
speed zones defined, which means the drive can write data at four  distinct
speeds. On a normal 1541 disk, these zones are as follows:

        Track Range      Speed Zone
        -----------      ----------
           1-17              3  (lowest writing speed)
          18-24              2
          25-30              1
        31 and up            0  (highest writing speed)

  Note that you can, through custom programming of  the  1541,  change  the
speed zone of any track to something different (change the 3 to  a  0)  and
write data differently. From the dump of the speed offset entries above, we
see that all the entries are in the range of 0-3. If any entry is less than
4, this is not considered a speed offset but defines the whole track to  be
recorded at that one speed.

  In the example I had, there were no offsets defined,  so  no  speed  zone
dump can be shown. However, I can define what should  be  there.  You  will
have a block of data, 1982 bytes long. Each byte is  encoded  to  represent
the speed of 4 bytes in the track  offset  area,  and  is  broken  down  as
follows:

  Speed entry $FF:  in binary %11111111
                               
                                  
                                   4'th byte speed (binary 11, 3 dec)
                                  3'rd byte speed (binary 11, 3 dec)
                                 2'nd byte speed (binary 11, 3 dec)
                                1'st byte speed (binary 11, 3 dec)

  It was very smart thinking to allow for two speed zone settings,  one  in
the offset block and another defining the speed on a per-byte basis. If you
are working with a normal disk, where each track  is  one  constant  speed,
then you don't need the extra blocks  of  information  hanging  around  the
image, wasting space.


  What may not be obvious is the flexibility of this format to  add  tracks
and speed offset zones at will. If a program decides to write a  track  out
with varying speeds, and no speed offset exist, a new block will be created
by appending it to the end of the image, and the offset  pointer  for  that
track set to point to the new block. If a track has no offset yet,  meaning
it doesn't exist (like a half-track), and one needs to be added,  the  same
procedure applies. The location of the actual track or speed zone  data  is
not important, meaning they do not have to be in any particular order since
they are all referenced by the offsets at the beginning of the image.


Analysing the GCR data
----------------------

  Since the information stored in the track data area is in GCR format,  it
is not as simple to analyse as a normal 256-byte sector would be.  We  need
to establish a "marker" by which one can start to interpret the data.  Here
is a dump of a portion of the GCR data, and what to look for...

      00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F        ASCII
      -----------------------------------------------   ----------------
0000: 0C 1E FF FF FF FF FF 52 54 B5 29 4B 7A 5E 95 55   RT)Kz^U
0010: 55 55 55 55 55 55 55 55 55 55 FF FF FF FF FF 55   UUUUUUUUUUU
0020: D4 A5 29 4A 52 94 A5 29 4A 52 94 A5 29 4A 52 94   ԥ)JR)JR)JR
0030: A5 29 4A 52 94 A5 29 4A 52 94 A5 29 4A 52 94 A5   )JR)JR)JR
0040: 29 4A 52 94 A5 29 4A 52 94 A5 29 4A 52 94 A5 29   )JR)JR)JR)
0050: 4A 52 94 A5 29 4A 52 94 A5 29 4A 52 94 A5 29 4A   JR)JR)JR)J
0060: 52 94 A5 29 4A 52 94 A5 29 4A 52 94 A5 29 4A 52   R)JR)JR)JR
0070: 94 A5 29 4A 52 94 A5 29 4A 52 94 A5 29 4A 52 94   )JR)JR)JR
0080: A5 29 4A 52 94 A5 29 4A 52 94 A5 29 4A 52 94 A5   )JR)JR)JR
0090: 29 4A 52 94 A5 29 4A 52 94 A5 29 4A 52 94 A5 29   )JR)JR)JR)
00A0: 4A 52 94 A5 29 4A 52 94 A5 29 4A 52 94 A5 29 4A   JR)JR)JR)J
00B0: 52 94 A5 29 4A 52 94 A5 29 4A 52 94 A5 29 4A 52   R)JR)JR)JR
00C0: 94 A5 29 4A 52 94 A5 29 4A 52 94 A5 29 4A 52 94   )JR)JR)JR
00D0: A5 29 4A 52 94 A5 29 4A 52 94 A5 29 4A 52 94 A5   )JR)JR)JR
00E0: 29 4A 52 94 A5 29 4A 52 94 A5 29 4A 52 94 A5 29   )JR)JR)JR)
00F0: 4A 52 94 A5 29 4A 52 94 A5 29 4A 52 94 A5 29 4A   JR)JR)JR)J
0100: 52 94 A5 29 4A 52 94 A5 29 4A 52 94 A5 29 4A 52   R)JR)JR)JR
0110: 94 A5 29 4A 52 94 A5 29 4A 52 94 A5 29 4A 52 94   )JR)JR)JR
0120: A5 29 4A 52 94 A5 29 4A 52 94 A5 29 4A 52 94 A5   )JR)JR)JR
0130: 29 4A 52 94 A5 29 4A 52 94 A5 29 4A 52 94 A5 29   )JR)JR)JR)
0140: 4A 52 94 A5 29 4A 52 94 A5 29 4A 52 94 A5 29 4A   JR)JR)JR)J
0150: 52 94 A5 29 4A 52 94 A5 29 4A 52 94 A5 29 4A 52   R)JR)JR)JR
0160: 94 A5 29 4A 55 55 55 55 55 55 FF FF FF FF FF 52   )JUUUUUUR
0170: 54 A5 2D 4B 7A 5E 95 55 55 55 55 55 55 55 55 55   T-Kz^UUUUUUUUU
0180: 55 55 FF FF FF FF FF 55 D4 A5 29 4A 52 94 A5 29   UUUԥ)JR)
0190: 4A 52 94 A5 29 4A 52 94 A5 29 4A 52 94 A5 29 4A   JR)JR)JR)J
01A0: 52 94 A5 29 4A 52 94 A5 29 4A 52 94 A5 29 4A 52   R)JR)JR)JR
01B0: 94 A5 29 4A 52 94 A5 29 4A 52 94 A5 29 4A 52 94   )JR)JR)JR
01C0: A5 29 4A 52 94 A5 29 4A 52 94 A5 29 4A 52 94 A5   )JR)JR)JR

  Always look for the group of five 'FF' bytes, as they establish the  SYNC
mark. Remember that the 1541 writes out a SYNC mark of  40  'on'  bits,  or
five 'FF's in a row. Note that there are *2* groups  of  SYNC  marks  quite
close together, one for the sector header and one for the sector data.

  Note that if the GCR data is not in  the  standard  sector  layout,  then
anything goes for interpreting the data. If no standard SYNC  mark  can  be
found, then there is no simple way to extract any useful data.