Jet Set Willy 128: Music format

The JSW128 music system is built around Ian Collier's TUNE.BIN. (Note: The files in that .zip use the obsolete "ZXF1" format; here are .TAP versions of MAKETUNE and PLAYTUNE. To use them, use a 128k emulator, but select 48 BASIC; otherwise the memory paging goes belly-up).

Documentation for Ian Collier's music programs (scroll down to find MAKETUNE).

To write a tune, you either have to use MAKETUNE, or manually construct one yourself. Either way, it helps to have a closer look at the .TUN file format.

+3DOS header - 128 bytes

This is present on the .TUN files in JSW128 distributions, but not on the original .TUN files. It is entirely optional if you are making JSW128 as a .TAP; it is compulsory if you are making a +3DOS disc version.

If you are creating a completely new .TUN, it's best to leave the +3DOS header off. It can be generated automatically later if necessary.

.TUN header - 6 bytes

This header consists of the addresses of the three channels of the tune (corresponding to the three strings in a PLAY command):

	DEFW	channel1
	DEFW	channel2
	DEFW	channel3

For a title screen tune, the first channel should always be at 30000. For an in-game tune, the first channel should always be at 63238. JSW64 also supports a cheat-mode tune, which should be at 63746.

I'll come back to the header after I've covered the remainder of the file.

.TUN data

The rest of the .TUN is composed of the data for the three channels. Each channel is a string of commands, which may be followed by one or two parameter bytes. The unit used for time is the "jiffy" - 1/50 of a second.

Command   Parameters  Meaning
=====================================================================
000       1 byte      Rest. The parameter byte is the length of the
                      rest, in jiffies.
001-248   1 byte      Play a note. The instruction byte is in 
                      semitones, with 48 being middle C. This is 
                      the same scale as BEEP, except you start at
                      48 instead of 0.
                      The parameter byte is the length of the note,
                      in jiffies.
249       1 byte      Set the waveform effect (like "W" in the PLAY 
		      command). The parameter byte is the waveform.
250       1 byte      Set the waveform period (like "X" in the PLAY 
                      command). The parameter byte is the duration;
                      don't know the units.
251       1 byte      Set the volume (like "V" in the PLAY command).
                      The parameter byte is the volume. If you want to
                      use a waveform effect, you should first set the 
                      volume to 16, then set the effect, and then the period.
252       3 bytes     "djnz" - used to repeat sections. The first and 
                      second parameters should both be set to the number
		      of repeats; the third is the relative address of the 
	              start of the section:
			 252: Section starts at the DJNZ
                         251: Section starts 1 byte before the DJNZ
                         250: Section starts 2 bytes before the DJNZ
                         ...
                         128: Section starts 124 bytes before the DJNZ
		      Warning: I've only seen this used in
                      title-screen tunes. I don't know how it would get on in
                      an in-game tune.
253       0 bytes     Return from a sub-tune - see below
254       2 bytes     Play a "sub-tune", which must end with a
                      "return" instruction (253). The two bytes are the
                      address of the sub-tune, in standard Z80 format 
                      (little-endian).
255       0 bytes     End of channel. All tunes must end with one of 
                      these.

Calculating addresses

So, you've worked out the bytes for your three channels. Here's how to combine them into a .TUN file.

  1. Choose if it's a starting tune or an in-game tune. Starting tunes can occupy up to 2775 bytes (that's all three channels plus 6 bytes of header); In-game tunes can occupy 256 (again, 3 channels plus the header).
  2. Work out the channel addresses. For a starting tune, these will be:

    (note that MAKETUNE generates tunes at this address, which makes things quite easy; if you get on well enough with MAKETUNE, you can use it for title screen tunes).

    For an in-game tune, the addresses will be:

    which are not supported by MAKETUNE.

  3. Once all the addresses are right, arrange the file in the order: and save it as a .TUN file.

Example

The current in-game tune, GRACE.TUN, looks like this:

	DEFW	TF706	;63238
	DEFW	TF737	;63287
	DEFW	TF768	;63336
;
; Channel 1
;
TF706:	DEFB	251, 7	;Volume 7
	DEFB	64, 50	;Note lasts 1 sec.
	DEFB	64, 43	;Note lasts 6/7 sec.
	...
	DEFB	38, 200	;Note lasts 4 sec.
	DEFB	255	;End
;
; Channel 2
;
TF737:	DEFB	251,6	;Volume 6
	DEFB	57, 32	;Note lasts 0.64 sec.
	DEFB	57, 32	;Note lasts 0.64 sec.
	...
	DEFB	54, 200 ;Note lasts 4 sec.
	DEFB	255	;End
;
; Channel 3
;
TF768:	DEFB	251,8	;Volume 8
	DEFB	66, 32	;Note lasts 0.64 sec.
	DEFB	66, 16	;Note lasts 0.32 sec.
	...
	DEFB	62,200	;Note lasts 4 sec.
	DEFB	255	;End


John Elliott 12-9-2000