.tic File Format - nesbox/TIC-80 GitHub Wiki
This is the specification for the .tic
file format used by TIC-80 cartridges.
Overview
TIC-80 cartridge files consist of several chunks of data, which contain the various assets of a game (i.e. the code, sprites, map, audio and cover image).
Chunk Format
Each chunk consists of a 4-byte header, followed by the chunk data. This pattern is then repeated for each chunk.
Offset | Bits (7...0) | Description |
---|---|---|
0 | BBBCCCCC |
B = Bank number (0...7), C = Chunk type (0...31) |
1...2 | SSSSSSSS SSSSSSSS |
Size of chunk (16 bits, max. 65535 bytes) |
3 | Reserved for future use | |
4+ | DDDDDDDD |
Chunk data |
The 16-bit size value is stored in little-endian order. That is to say, offset 1 stores the eight least-significant bits, while offset 2 stores the eight most-significant bits.
The code/binary chunks can store up to 65536 bytes of data, which the 16-bit size number represents as 0 since 65536 cannot fit inside 16 bits. So there cannot exist code/binary chunks with no data since size 0 represents 65536.
There is a bug; when saving a full 65536 characters (the actual maximum size for TIC-80 code), the 16-bit size number will wrap around. This causes the code editor to become empty, and interprets the code's text as if it were the following chunks.
Chunk Types
Certain chunk types are of fixed size, for example the sprite sheets and map, and these are zero-extended such that sprite pixels and map cells have a zero value. Unbanked chunks ignore the B
bank bits as described previously.
The following are based on the ChunkType
enum in cart.c:
Type | Chunk | Banks | Notes |
---|---|---|---|
1 | CHUNK_TILES | 8 | |
2 | CHUNK_SPRITES | 8 | |
4 | CHUNK_MAP | 8 | |
5 | CHUNK_CODE | 8 | |
6 | CHUNK_FLAGS | 8 | |
9 | CHUNK_SAMPLES | 8 | |
10 | CHUNK_WAVEFORM | ||
12 | CHUNK_PALETTE | ||
14 | CHUNK_MUSIC | 8 | |
15 | CHUNK_PATTERNS | 8 | |
17 | CHUNK_DEFAULT | ||
18 | CHUNK_SCREEN | 8 | |
19 | CHUNK_BINARY | 4 | |
3 | CHUNK_COVER_DEP | deprecated as of 0.90 | |
13 | CHUNK_PATTERNS_DEP | 8 | deprecated as of 0.80 |
16 | CHUNK_CODE_ZIP | deprecated as of 1.00 | |
7, 8, 11 | (reserved) ... | ||
19..31 | (reserved) ... |
Tiles
- Chunk Type: 1
This represents the background sprites (or 'tiles') (0...255). This is copied to RAM at0x4000
...0x5FFF
.
Seeing as TIC-80 supports only 16 colors and a byte goes up to 255 as a compression method two pixels are stored in 1 byte, same in sprites chunk
Sprites
- Chunk Type: 2
This represents the foreground sprites (256...511). This is copied to RAM at0x6000
...0x7FFF
.
Cover Image
- Chunk Type: 3
This is the GIF image file that is displayed to the user in SURF mode and appears on the website. The bank bits are ignored.
Note: This chunk is deprecated as of 0.90 and replaced by bank 0 of Screen chunk.
Map
- Chunk Type: 4
This represents the map data. This is copied to RAM at0x8000
...0xFF7F
.
Code
- Chunk Type: 5
This represents the code, in ASCII text format.
Version Notes:
-
0.80 removed support for separate code banks. Older cartridge's discrete banks will be loaded into a single codebase (with a newline between each) - starting at bank 7 (which appears at the top) and working backwards to bank 0. The bank number is therefore deprecated in version 0.80.
-
1.0 supports up to 512kb of code. This code is stored sequentially (uncompressed) across up to 8 banks. Individual banks are joined into a single large string when loaded (in sequential 0..7 order). The editor buffer split into multiple banks when saved to cartridge (when larger than 64kb). A cartridge may consist of 1 to 8 code banks.
Flags
- Chunk Type: 6
This represents the sprite flags data. This is copied to RAM at 0x14404
...0x14603
.
This chunk stores flag data for each sprite as a single bytes where each bit indicates if the flag is set for the specific sprite or not
This chunk type was added with version 0.80.
SFX
- Chunk Type: 9
This represents the sound effect data. This is copied to RAM at0x100E4
...0x11163
.
Each sound effect in this chunk is represented by 66 bytes of data (trailing zeros are removed), they follow this structure :
Ids | Structure | Description |
---|---|---|
1-60 | VWVW...VW | V is the volume byteW is the wave byte |
61 | DXSSSOOO | D stores if the arpeggio is in the "down" directionX stores if the pitch is to be multiplied by 16xS stores the sample speedO stores the notes octave (0-7) |
62 | -----NNN | N is the note number (0-7 -> C-B) |
63-65 | LLLLFFFF | L is the loop lengthF is the loop start |
Notes :
- The volume byte should be subtracted from 15 to get the correct volume as shown in the editor (15 - V)
- The sample speed bytes should added to 4 and then you should preform the modulus operation with 8 on it ((S + 4) % 8)
Waveforms
- Chunk Type: 10
This represents the sound wave-table data. This is copied to RAM at0x0FFE4
...0x100E3
.
This chunk stores the various waveforms used by sound effects. Due to the fact that waveforms heights go from 0 to 15 is is possible to store 2 height in 1 byte, this is why waveforms are 16 bytes but in the editor there are 32 points you can edit.
Palette
- Chunk Type: 12
This represents the palette data. Prior to 0.70.6, the bank bits were ignored and the palette was used across all graphics/map banks. In 0.70.6 and above, each bank gets its own palette.
This chunk type is 96 bytes long: 48 bytes for the SCN
palette, followed by 48 bytes for the OVR
palette. The SCN
palette is copied to RAM at0x3FC0
...0x3FEF
.
Note: If no palette chunk is specified for bank 0, then the bank will have the DB16 palette for SCN
, and the OVR
palette will be left blank. This preserves compatibility with ancient carts without a palette chunk defined.
Music Patterns (deprecated)
- Chunk Type: 13
This represents the music pattern data. This is copied to RAM at 0x11164
...0x13E63
. This is the old variation which is deprecated.
This chunk was deprecated with 0.80.
As of 0.80, it is automatically converted to a new format used by type 15.
Music Tracks
- Chunk Type: 14
This represents the music track data. This is copied to RAM at 0x13E64
...0x13FFB
.
This chunk contains the various music tracks, as composed of 51 bytes where trailing zeros are removed, the structure is as follows
Ids | Structure | Description |
---|---|---|
1-48 | FFFFFFSSSSSSTTTTTTQQQQQQ | The bytes here are arranged in triplets whereF is the number of the pattern on the first channelS is the number of the pattern on the second channelT is the number of the pattern on the third channelQ is the number of the pattern on the fourth channel |
49 | SSSSSSSS | S is the speed of the track |
50 | RRRRRRRR | R is the number of rows in each pattern |
51 | TTTTTTTT | T is the tempo of the track |
Notes :
- Although the individual notes are stored as 6 bits in the editor the maximum number that can be used is 60 (may be possible to insert illegal pattern in music tracks?)
- To get the correct speed of the track do: (S + 6) % 255
- To get the correct number of rows of the track do: 64 - R
- To get the correct tempo of the track do: T + 150
Music Patterns
- Chunk Type: 15
This represents the music pattern data. This is copied to RAM at 0x11164
...0x13E63
. This is a new variation with support for effect commands.
Each pattern is 192 bytes long (trailing zeros are removed). Each note in a patters is represented by a triplet of bytes, like this:
----NNNN SCCCAAAA OOOSSSSS
Explanation :
- N is the note number (4-15 for notes and <4 for stops)
- S is the sfx number (the part in byte 2 is to be added to the one in byte 3 after shifting it to the left 2 times)
- C is the command to be performed on the note (0-7 -> MCJSPVD)
- A is the x and y arguments for each command
- O is the octave of each note
This chunk type was added with version 0.80.
Code (Compressed)
- Chunk Type: 16
This represents the code, compressed with ZLIB. If code in the editor goes beyond the 64K chunk limit, TIC-80 will compress it provided that the compressed result does not exceed 64K. The bank bits are ignored.
This chunk type was added with version 0.80.
Default
- Chunk Type: 17
This chunk serves as a flag for whether the default palette and waveforms should be loaded or not.
Screen
- Chunk Type: 18
Stores a 240 x 136 x 4bpp raw buffer (ie, VRAM). This chunk is always 16kb. Bank 0 is used for the cover image.
This chunk type was added with version 0.90.
Binary
- Chunk Type: 19
Stores a binary representation of code. Used to store binary WASM files for WASM cartridges.
This chunk type will be added with version 1.0.
All other chunk types
Any chunk type not listed above is reserved for future use.