mirror of
https://github.com/aaru-dps/docs.git
synced 2025-12-16 11:14:37 +00:00
511 lines
22 KiB
Plaintext
511 lines
22 KiB
Plaintext
|
|
*** SID/PSID (Various SIDPlay / PlaySID Formats)
|
|
*** Document revision: 1.2
|
|
*** Last updated: March 15, 2004
|
|
*** Compiler/Editor: Peter Schepers
|
|
*** Contributors/sources: LaLa,
|
|
Peter Weighill
|
|
|
|
The data files used by SIDPLAY contain binary C64 data and music player
|
|
machine code. Both, the programmer on the C64 and this emulator need
|
|
information on how to access the code inside the binary file. That means,
|
|
information like the memory location to load the file to, the number of
|
|
tunes, the starting address of the executable code and its subroutines.
|
|
This specific information has to be delivered in either a separate file -
|
|
which is often called info file - or in form of a header in the single
|
|
binary data file. A standalone C64 data file without a header or without a
|
|
corresponding info file is considered invalid.
|
|
|
|
It is recommended that you get accustomed to one-file sidtunes with the
|
|
*.sid extension. For raw C64 binary files the extension .c64 or .prg is
|
|
preferred in order to be able to assign a .sid extension to the additional
|
|
info file.
|
|
|
|
Supported and merely used file formats are:
|
|
|
|
PlaySID single-file-format (widely known as PSID)
|
|
|
|
PlaySID info-file-format (Raw C64 binary file plus Amiga Workbench icon
|
|
tooltype file .INFO)
|
|
|
|
SIDPLAY info-file-format (Raw C64 binary file plus SIDPLAY ASCII text
|
|
info file, previously .SID)
|
|
|
|
C64 Sidplayer format (.MUS/.STR)
|
|
|
|
Raw data or PSID files have appeared as *.data, *.psid or psid.*.
|
|
|
|
|
|
DAT files
|
|
|
|
The .DAT file name extension has been introduced by the early versions of
|
|
SIDPLAY/DOS. It has never been used to specify a file format. Its main use
|
|
has been in assigning a unique file name extension to any sidtune file, but
|
|
especially raw C64 data files, and allowing to use .SID for additional info
|
|
files.
|
|
|
|
|
|
INFO files
|
|
|
|
These are Amiga Workbench tooltype icons containing binary graphics data
|
|
and ASCII text information strings. They have been used by PlaySID and are
|
|
supported by SIDPLAY. Their file name extension normally is .info or .INF.
|
|
This is a two-file format. A separate C64 binary data file is required. On
|
|
Amiga the corresponding C64 data files usually haven't had filename
|
|
extensions. However, they might have been renamed on other systems.
|
|
|
|
|
|
SIDPLAY info files
|
|
|
|
These are plain ASCII text files which have been introduced by the
|
|
earlier versions of SIDPLAY/DOS. They are used to be able to alter the
|
|
information inside with a normal ASCII text editor. They can be converted
|
|
to a single file that contains a binary header. This is a two-file format.
|
|
A separate C64 binary data file is required. Notice that each pair of files
|
|
usually has the old DOS-naming of .SID for the info file and .DAT for the
|
|
C64 data file.
|
|
|
|
The SIDPLAY info file is derived from the information inside the PlaySID
|
|
one-file format. It is structured like this:
|
|
|
|
SIDPLAY INFOFILE
|
|
ADDRESS=<loadAddress>,<initAddress>,<playAddress>
|
|
SONGS=<total>[,<start>]
|
|
SPEED=<hexValue>
|
|
NAME=<name of music/tune>
|
|
AUTHOR=<name of author/composer>
|
|
COPYRIGHT=<year/name of copyright owner/company>
|
|
RELEASED=<year/name of copyright owner/company>
|
|
SIDSONG=<YES|NO>
|
|
RELOC=<hexValue>,<hexValue>
|
|
CLOCK=<PAL|NTSC>
|
|
SIDMODEL=<6581|8580>
|
|
COMPATIBILITY=<R64|BASIC>
|
|
|
|
The first line of the text containing ``SIDPLAY INFOFILE'' is only used
|
|
to identify the type of file.
|
|
|
|
ADDRESS=<loadAddress>,<initAddress>,<playAddress>
|
|
|
|
Each specified address is a 16-bit effective C64 memory location in case
|
|
insensitive hexa-decimal notation without a prefix, e.g. C000 or E012, but
|
|
neither $FCE2 nor 0xFCE2. Preceding zeroes are ignored.
|
|
|
|
<loadAddress> is the C64 memory location where to put the C64 data. 0
|
|
means, the data is in original C64 format, i.e. the first two bytes contain
|
|
the little-endian load address (low byte, high byte). Please don't
|
|
explicitly specify the load address unless required for sure. If the load
|
|
address is explicitly specified, some sidtune converters and utilities
|
|
conjecture that the C64 data lacks its load address. Hence they move it in
|
|
front of the C64 data. This would create two redundant bytes if the C64
|
|
data already had a load address in the first two bytes. Additionally, those
|
|
extra bytes in the beginning can confuse disassemblers.
|
|
|
|
<initAddress> is the start address of the machine code subroutine that
|
|
initializes a song by accepting the contents of the 8-bit 6510 Accumulator
|
|
as the song number parameter. 0 means, the address is equal to the
|
|
effective load address.
|
|
|
|
<playAddress> is the start address of the machine code subroutine that can
|
|
be called frequently to produce a continuous sound. 0 means, the
|
|
initialization subroutine is expected to install an interrupt handler,
|
|
which then calls the music player. If so, the value in the bank-select
|
|
register $01 determines whether the IRQ vector $0314/$0315 (Kernal-ROM on)
|
|
or the IRQ vector $FFFE/$FFFF (Kernal-ROM off) is to be used.
|
|
|
|
SONGS=<total>,[<start>]
|
|
|
|
<total> is the decimal number of songs (or sound effects) that can be
|
|
initialized by calling the init address. The minimum is 1.
|
|
|
|
<start> is the decimal number of the song to be played by default. This
|
|
value is meant as a proposal and is optional. It has a default of 1. It
|
|
often specifies the first song you would hear upon starting the program is
|
|
has been taken from.
|
|
|
|
SPEED=<value>
|
|
|
|
<value> is a value in case insensitive hexa-decimal notation without a
|
|
prefix. Preceding zeroes are ignored. The value contains information about
|
|
the speed of each song. For each song a bit is reserved, bit 0 for song 1,
|
|
bit 1 for song 2, and so on. A bit set to 0 means, the music player
|
|
subroutine is called at 50 Hz. A bit set to 1 means, the real speed is
|
|
indicated by the CIA 1 Timer A $DC04/05, which defaults to 60 Hz. To not
|
|
break compatibility to the PlaySID formats, use a maximum of 32 bits, which
|
|
is equal to 32 songs. Due to a bug in PlaySID, the PSID format can only
|
|
handle up to 8 songs correctly. On the contrary, the SIDPLAY info format is
|
|
extended to 256 bits, which is equal to 256 songs. Examples: SPEED=0
|
|
replays every song at 50 Hz speed. SPEED=1F replays songs 1-5 at 60 Hz
|
|
speed, all other songs at 50 Hz speed.
|
|
|
|
NAME=<name of music/tune>
|
|
AUTHOR=<name of author/composer>
|
|
RELEASED=<year/name of copyright owner/company>
|
|
or
|
|
COPYRIGHT=<year/name of copyright owner/company>
|
|
|
|
These three fields are all plain ASCII text strings. There are limited to
|
|
a maximum of 80 characters each. To not break compatibility to the PlaySID
|
|
formats, use a maximum of 31 characters.
|
|
|
|
SIDSONG=<YES|NO>
|
|
|
|
is used to indicate that the corresponding C64 data file is in (Enhanced)
|
|
Sidplayer file format. This field is optional and defaults to NO.
|
|
|
|
RELOC=<hexValue>,<hexValue>
|
|
|
|
is used to indicate a free memory range not used by the sid tune. (e.g.
|
|
RELOC=04,65)
|
|
|
|
CLOCK=<PAL|NTSC>
|
|
|
|
is used to indicate the type of C64 the tune was original written for.
|
|
|
|
SIDMODEL=<6581|8580>
|
|
|
|
is used to indicate the type of sid chip the tune was original written
|
|
for.
|
|
|
|
COMPATIBILITY=<R64|BASIC>
|
|
|
|
is used to indicate the compatibility mode of the sid tune. Normally this
|
|
would not be included but is set to R64 when the tune includes "sample"
|
|
music and will only play correctly on a real c64 or a newer sidplayer. This
|
|
is set to BASIC when the .dat file contains BASIC code.
|
|
|
|
An example file ``EXAMPLE.SID'' may look like this:
|
|
|
|
SIDPLAY INFOFILE
|
|
ADDRESS=2AF0,3002,300C
|
|
SONGS=3,2
|
|
SPEED=0
|
|
NAME=Example
|
|
AUTHOR=Example
|
|
RELEASED=199? (c) Example
|
|
SIDSONG=NO
|
|
|
|
|
|
PSID/RSID file header
|
|
|
|
The detailed structure of the SID header looks like the following. Header
|
|
offsets are in hexadecimal notation. Other integer values are decimal
|
|
unless explicitly marked otherwise. Any stored integer values are in
|
|
big-endian format:
|
|
|
|
+00 magicID: ``PSID'' or ``RSID''
|
|
|
|
This is a four byte long ASCII character string containing the value
|
|
0x50534944 or 0x52534944. 'RSID' (Real SID) denotes that the file strictly
|
|
requires a true Commodore-64 environment to run properly. 'PSID' files will
|
|
generally run trouble-free on older PlaySID and libsidplay1 based
|
|
emulators, too.
|
|
|
|
|
|
Some words about the Real C64 SID file format (RSID):
|
|
|
|
The RSID format was designed to contain tunes that are not PlaySID
|
|
compatible, but strictly require a real C64 environment to run. Tunes that
|
|
are multi-speed and/or contain samples and/or use additional interrupt
|
|
sources or do busy looping will cause older SID emulators to lock up or
|
|
play very wrongly (if at all).
|
|
|
|
By using the name RSID for such rips all existing SID emulators will
|
|
reject these tunes safely until they can be upgraded to cope with the
|
|
additional requirements.
|
|
|
|
Due to the nature of these tunes, every effort must be made to make sure
|
|
they are directly runnable on an actual C64 computer. As such the tunes
|
|
will only be presented with the default C64 power-on environment and
|
|
expected to configure and use all hardware appropriately.
|
|
|
|
|
|
RSID is based on PSIDv2NG with the following modifications:
|
|
|
|
magicID = RSID
|
|
version = only 2
|
|
loadAddress = 0 (reserved)
|
|
playAddress = 0 (reserved)
|
|
speed = 0 (reserved)
|
|
psidSpecific flag is called C64BASIC flag
|
|
|
|
The above fields MUST be checked and if any differ from the above then
|
|
the tune MUST be rejected. The definitions above will force tunes to
|
|
contain proper hardware configuration code and install valid interrupt
|
|
handlers.
|
|
|
|
|
|
The default C64 environment is as follows:
|
|
|
|
VIC - IRQ set to raster 0, but not enabled.
|
|
CIA 1 timer A - set to 60Hz with the counter running and IRQs active.
|
|
Other timers - disabled and loaded with $FFFF.
|
|
Bank register - $37
|
|
|
|
A side effect of the bank register is that init MUST NOT be located under
|
|
a ROM/IO memory area (addesses $0000-$07E8, $A000-$BFFF and $D000-$FFFF).
|
|
Since every effort needs to be made to run the tune on a real C64 the load
|
|
address of the image MUST NOT be set lower than $07E8.
|
|
|
|
+04 WORD version
|
|
|
|
Available version number can either be 0001 or 0002. Headers of version 2
|
|
provide additional fields. RSID and PSID v2NG files must have 0002 here.
|
|
|
|
+06 WORD dataOffset
|
|
|
|
This is the offset from the start of the file to the C64 binary data
|
|
area. Because of the fixed size of the header, this is either 0x0076 for
|
|
version 1 and 0x007C for version 2.
|
|
|
|
+08 WORD loadAddress
|
|
|
|
The C64 memory location where to put the C64 data. 0 means the data are
|
|
in original C64 binary file format, i.e. the first two bytes of the data
|
|
contain the little-endian load address (low byte, high byte). This must
|
|
always be true for RSID files. Furthermore, the actual load address must
|
|
NOT be less than $07E8 in RSID files.
|
|
|
|
You must be absolutely sure what to enter here. There is no way to detect
|
|
automatically whether the first two bytes in a C64 data file are meant to
|
|
be a load address or some arbitrary bytes of code or data. Unless your C64
|
|
file is not a normal binary file and thus has no load address in front, you
|
|
need not enter anything else than 0 here. The SID tune will not play if you
|
|
specify a load address which is present in the C64 file already.
|
|
|
|
Normal C64 binary data files have a load address in their first two
|
|
bytes, so they can be loaded to a pre-defined destination address by
|
|
executing LOAD"FILE",8,1, for instance. If a load address is explicitly
|
|
specified in the sidtune info file, some sidtune converters and utilities
|
|
conjecture that the C64 data don't have a load address in their first two
|
|
bytes. Hence, the explicit load address from the info file is moved in
|
|
front of the C64 data to create a valid C64 binary file which can be easily
|
|
loaded on a C64, too. If that C64 file were to be saved, it would contain
|
|
two superfluous data bytes at offset 2 if an original load address had been
|
|
in the first two bytes of the old file. This process of adding a duplicate
|
|
load address can be repeated. The file loader strips off the first two
|
|
bytes (the used load address) and puts the rest of the file contents
|
|
(including the now obsolete load address at file offset 2) into memory. If
|
|
the new load address is the same than the old one the two added bytes cause
|
|
the whole data to be displaced by two bytes, which most likely results in
|
|
malfunctioning code. Also, superfluous bytes in memory then can confuse
|
|
disassemblers which start at the beginning of the file or memory buffer.
|
|
|
|
+0A WORD initAddress
|
|
|
|
The start address of the machine code subroutine that initializes a song,
|
|
accepting the contents of the 8-bit 6510 Accumulator as the song number
|
|
parameter. 0 means the address is equal to the effective load address.
|
|
|
|
In RSID files initAddress must never point to a ROM area ($A000-$BFFF or
|
|
$D000-$FFFF) or be lower than $07E8. Also, if the C64 BASIC flag is set,
|
|
initAddress must be 0.
|
|
|
|
+0C WORD playAddress
|
|
|
|
The start address of the machine code subroutine that can be called
|
|
frequently to produce a continuous sound. 0 means the initialization
|
|
subroutine is expected to install an interrupt handler, which then calls
|
|
the music player at some place. This must always be true for RSID files.
|
|
|
|
+0E WORD songs
|
|
|
|
The number of songs (or sound effects) that can be initialized by calling
|
|
the init address. The minimum is 1. The maximum is 256.
|
|
|
|
+10 WORD startSong
|
|
|
|
The song number to be played by default. This value is optional. It often
|
|
specifies the first song you would hear upon starting the program is has
|
|
been taken from. It has a default of 1.
|
|
|
|
+12 LONGWORD speed
|
|
|
|
This is a 32 bit big endian number. Each bit in 'speed' specifies the
|
|
speed for the corresponding tune number, i.e. bit 0 specifies the speed for
|
|
tune 1. If there are more than 32 tunes, the speed specified for tune 32 is
|
|
also used for all higher numbered tunes.
|
|
|
|
A 0 bit specifies vertical blank interrupt (50Hz PAL, 60Hz NTSC), and a 1
|
|
bit specifies CIA 1 timer interrupt (default 60Hz).
|
|
|
|
Surplus bits in 'speed' should be set to 0.
|
|
|
|
For RSID files 'speed' must always be set to 0.
|
|
|
|
Note that if 'play' = 0, the bits in 'speed' should still be set for
|
|
backwards compatibility with older SID players. New SID players running in
|
|
a C64 environment will ignore the speed bits in this case.
|
|
|
|
WARNING: This field does not work in PlaySID for Amiga like it was
|
|
intended, therefore the above is a redefinition of the original 'speed'
|
|
field in SID v2NG! See also the 'clock' (video standard) field described
|
|
below for 'flags'.
|
|
|
|
+16 ``<name>''
|
|
+36 ``<author>''
|
|
+56 ``<released>'' (also known as ``<copyright>'')
|
|
|
|
These are 32 byte long zero terminated ASCII character strings. Upon
|
|
evaluating the header, a zero byte will always be put into the last byte of
|
|
each string. So the maximum number of available free characters is 31.
|
|
|
|
+76 <data>
|
|
|
|
Version 1 of the SID header is complete at this point. The binary C64
|
|
data starts here.
|
|
|
|
Version 2 of the header incorporates the v1 header fields and provides
|
|
additional fields. Some of these are actually v2NG specific - those are
|
|
noted below.
|
|
|
|
+76 WORD flags
|
|
|
|
|
|
This is a 16 bit big endian number containing the following bitfields:
|
|
|
|
Bit 0 specifies format of the binary data (musPlayer):
|
|
0 = built-in music player,
|
|
1 = Compute!'s Sidplayer MUS data, music player must be merged.
|
|
|
|
If this bit is set, the appended binary data are in Compute!'s Sidplayer
|
|
MUS format, and does not contain a built-in music player. An external
|
|
player machine code must be merged to replay such a sidtune.
|
|
|
|
Bit 1 specifies whether the tune is PlaySID specific, e.g. uses PlaySID
|
|
samples (psidSpecific):
|
|
0 = C64 compatible,
|
|
1 = PlaySID specific (PSID v2NG)
|
|
1 = C64 BASIC flag (RSID)
|
|
|
|
This is a v2NG and RSID specific field.
|
|
|
|
PlaySID samples were invented to facilitate playback of C64 volume
|
|
register samples with the original Amiga PlaySID software. PlaySID samples
|
|
made samples a reality on slow Amiga hardware with a player that was
|
|
updated only once a frame.
|
|
|
|
Unfortunately, converting C64 volume samples to PlaySID samples means
|
|
that they can no longer be played on a C64, and furthermore the conversion
|
|
might potentially break the non-sample part of a tune if the timing between
|
|
writes to the SID registers is at all altered. This follows from the ADSR
|
|
bugs in the SID chip.
|
|
|
|
Today, the speed of common hardware and the sophistication of the SID
|
|
players is such that there is little need for PlaySID samples. However,
|
|
with all the PlaySID sample PSIDs in existence there's a need to
|
|
differentiate between SID files containing only original C64 code and PSID
|
|
files containing PlaySID samples or having other PlaySID specific issues.
|
|
As stated above, bit 1 in 'flags' is reserved for this purpose.
|
|
|
|
Since RSID files do not have the need for PlaySID samples, this flag is
|
|
used for a different purpose: tunes that include a BASIC executable portion
|
|
will be played (with the BASIC portion executed) if the C64 BASIC flag is
|
|
set. At the same time, initAddress must be 0.
|
|
|
|
Bits 2-3 specify the video standard (clock):
|
|
00 = Unknown,
|
|
01 = PAL,
|
|
10 = NTSC,
|
|
11 = PAL and NTSC.
|
|
|
|
This is a v2NG specific field.
|
|
|
|
As can be seen from the 'speed' field, it is not possible to specify NTSC
|
|
C64 playback. This is unfortunate, since the different clock speeds means
|
|
that a tune written for the NTSC C64 will be slightly detuned if played
|
|
back on a PAL C64. Furthermore, NTSC C64 tunes driven by a vertical blank
|
|
interrupt have to be converted to use the CIA 1 timer to fit into this
|
|
scheme. This can cause severe problems, as the NTSC refresh rate is once
|
|
every 17045 cycles, while the CIA 1 timer A is latched with 17095 cycles.
|
|
Apart from the difference in timing itself, the SID ADSR bugs can actually
|
|
break the tune.
|
|
|
|
The 'clock' (video standard) field was introduced to circumvent this
|
|
problem.
|
|
|
|
Bits 4-5 specify the SID version (sidModel):
|
|
00 = Unknown,
|
|
01 = MOS6581,
|
|
10 = MOS8580,
|
|
11 = MOS6581 and MOS8580.
|
|
|
|
This is a v2NG specific field.
|
|
|
|
The MOS6581 and the MOS8580 have three notable differences. First,
|
|
combined waveforms are generally louder on a MOS8580, to the extent that
|
|
some combinations that are clearly audible on a MOS8580 are completely
|
|
silent on a MOS6581. Second, the internal DC levels in the MOS8580 are so
|
|
small that software or hardware tricks must be used to play volume samples.
|
|
Third, the MOS8580 analog filter has totally different characteristics from
|
|
the MOS6581 analog filter.
|
|
|
|
To ensure that music specifically written for one of the two SID versions
|
|
can be played back correctly, bits 4-5 in 'flags' are used as stated above.
|
|
|
|
Bits 6-15 are reserved and should be set to 0.
|
|
|
|
+78 BYTE startPage (relocStartPage)
|
|
|
|
This is a v2NG specific field.
|
|
|
|
This is an 8 bit number. If 'startPage' is 0, the SID file is clean, i.e.
|
|
it does not write outside its data range within the driver ranges. In this
|
|
case the largest free memory range can be determined from the start address
|
|
and the data length of the SID binary data. If 'startPage' is 0xFF, there
|
|
is not even a single free page, and driver relocation is impossible.
|
|
Otherwise, 'startPage' specifies the start page of the single largest free
|
|
memory range within the driver ranges. For example, if 'startPage' is 0x1E,
|
|
this free memory range starts at $1E00.
|
|
|
|
+79 BYTE pageLength (relocPages)
|
|
|
|
This is a v2NG specific field.
|
|
|
|
This is an 8 bit number indicating the number of free pages after
|
|
'startPage'. If 'startPage' is not 0 or 0xFF, 'pageLength' is set to the
|
|
number of free pages starting at 'startPage'. If 'startPage' is 0 or 0xFF,
|
|
'pageLength' must be set to 0.
|
|
|
|
The relocation range indicated by 'startPage' and 'pageLength' should
|
|
never overlap or encompass the load range of the C64 data. For RSID files,
|
|
the relocation range should also not overlap or encompass any of the ROM
|
|
areas ($A000-$BFFF and $D000-$FFFF) or the reserved memory area
|
|
($0000-$03FF).
|
|
|
|
+7A WORD reserved
|
|
|
|
This is a 16 bit number and is reserved and should be set to 0.
|
|
|
|
+7C <data>
|
|
|
|
Version 2 of the SID header ends here. This offset is the start of the
|
|
binary C64 data. See also 'loadAddress' for what the first 2 bytes of
|
|
'data' might indicate.
|
|
|
|
|
|
|
|
MUS files
|
|
|
|
The .MUS & .STR file name extensions are used for Compute's Sidplayer
|
|
music files.
|
|
|
|
The overall file layout is as follows:
|
|
The first two bytes contain the load address.
|
|
The next two bytes contain the length of the data for Voice 1
|
|
The next two bytes contain the length of the data for Voice 2
|
|
The next two bytes contain the length of the data for Voice 3
|
|
Then the data for Voice 1 follows immediately
|
|
Then the data for Voice 2 follows immediately
|
|
Then the data for Voice 3 follows immediately
|
|
Then the text description of the music file (upto 5 lines)
|
|
|
|
The data for each Voice consists of a stream of two byte commands and
|
|
should be terminated with a HALT code which is 01 4F.
|
|
|
|
The text description can be upto 5 lines long, each line upto 32
|
|
characters wide. It is made up of PETSCII characters and may contain colour
|
|
codes. The text description should be terminated with a 00 byte (but might
|
|
not be).
|
|
|