Difference between revisions of "Format:TAP tape image file format"

From CPCWiki - THE Amstrad CPC encyclopedia!
Jump to: navigation, search
Line 54: Line 54:
 
  Bit 0      Protection    If this bit is set the file is protected in some way  
 
  Bit 0      Protection    If this bit is set the file is protected in some way  
 
  Bits 1..3  File contents  0 = Internal BASIC
 
  Bits 1..3  File contents  0 = Internal BASIC
                          1 = Binary
+
                        1 = Binary
                          2 = Screen image
+
                        2 = Screen image
                          3 = ASCII
+
                        3 = ASCII
                          4..7 are unallocated
+
                        4..7 are unallocated
 
  Bits 4..7  Version        ASCII files should be version 1, all other files, version 0  
 
  Bits 4..7  Version        ASCII files should be version 1, all other files, version 0  
  

Revision as of 09:33, 28 April 2011

This document describes the TAP format for use in Amstrad CPC emulators, and a simple way to implement by trapping the ROM loader routine.

Tape-Image (.TAP) file format

The .TAP files contain blocks of tape-saved data. All blocks start with two bytes specifying how many bytes will follow (not counting the two length bytes). Then raw tape data follows, starting with the flag byte. Unlike speccy format, the checksum bytes are not included, so you don't need calculate the crc-ccitt every 256 bytes, or padding the last page with zeroes, or ending with four 0xff bytes trailer.

  1D 00 2C 50 68 61 6E 74 6F 6D 61 73 32 20 20 20 20 20 20 01 FF 02 58 00 00 AD FF

 ^^^^^...... first block is 29 bytes (28 bytes+flag)
       ^^... flag byte (A reg, 2C for headers, 16 for data blocks)
file name .^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
block number ..............................................^^
last block (a non-zero value means last block) ...............^^
file type (02 unprotected binary) ...............................^^
data length (88 bytes) .............................................^^^^^
data location (0xAD00) ...................................................^^^^^
first block (a non-zero value means first block) ...............................^^

58 00 10 AD 59 00 16 06 12 0A 00 2A 02 18 06 1E 07 30 0C 00 0D ..

^^^^^............... logical length, in consecutive blocks (88 bytes)
     ^^^^^......... execution address for machine code programs (0xAD10)
           ^^^^^... second block is 89 bytes (88 bytes+flag)
flag byte ........^^
second block data ...^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Note that it is possible to join .TAP files by simply stringing them together.

For example, in DOS / Windows:

    COPY /B FILE1.TAP + FILE2.TAP ALL.TAP

or in Unix/Linux:

    cp file1.tap all.tap && cat file2.tap >> all.tap

For completeness, I'll include the structure of a tape header. A header always consists of 28 bytes:

Byte Size  Name           Description
   0   16  Filename       Padded to 16 bytes with nulls
 16    1  Block number   Filename (padded with blanks)
 17    1  Last block     A non-zero value means that this is the last block of a file
 18    1  File type      A value recording  the type of the file (see below)
 19    2  Data length    The number of data bytes in the data record
 21    2  Data location  Where the data was written from originally
 23    1  First block    A non-zero value means that this is the first block of a file
 24    2  Logical length This is the total length of the file in bytes
 26    2  Entry address  The execution address for machine code programs

The file type (byte 18) is split into a number of fields:

Bit 0      Protection     If this bit is set the file is protected in some way 
Bits 1..3  File contents  0 = Internal BASIC
                        1 = Binary
                        2 = Screen image
                        3 = ASCII
                        4..7 are unallocated
Bits 4..7  Version        ASCII files should be version 1, all other files, version 0 

Trapping the ROM routine

The recommendable entry point in the Amstrad CPC ROM is a routine named "CAS READ", that has the next parameters:

 A = sync byte
HL = location of data
DE = length of data

So when you trap the routine, you must check that sync byte matches with A register and length of block-1 with DE register. Then copy from file to memory starting at HL address, and finally change the F register to 0x45 (no errors) and the PC with the exit point. Addresses are, in hexadecimal, in the next table:

             464 ROM   664 ROM  6128 ROM
Entry Point     2836      29A6      29A6
Exit Point      2872      29E2      29E2