There is a mplex factor that gives the speed of song. the timer is called with 1193000 / mplex Hz musics normally run with mplex 3000. music resource: int16 size int16 xxx int16 pcjr_offset speaker resource pcjr resource speaker resource: byte priority (low 7 bit: priority, high bit: sound is delayable */ byte xxx int16 xxx speaker sound chunks... /* SPEAKER sound chunks */ sound chunks: several types, first word is type chunk -1: marks end of track chunk -2: marks start of loop next chunk starts immediately chunk -3: marks end of loop loop to last chunk -2 chunk -4: reset sound system next chunk starts immediately chunk 0: int16 mplex several blocks of either: int16 note-length int16 freq (plays a tone of 1193000/freq Hz) or: int16 -5 (marks a variable (a script var?)) or: int16 0 (end of chunk) chunk 1: int16 mplex int16 start_freq int16 dest_freq int16 freq_delta int16 repeat_ctr chunk 2: int16 start_mplex int16 dest_mplex int16 mplex_delta /* speaker output is toggled on any interrupt */ chunk 3: (Complicated random noise) int16 start_mplex int16 dest_mplex int16 mplex_delta the mplex is anded with a LSR to produce random frequencies. /* PCjr sound chunks */ pcjr resource: byte priority (low 7 bit: priority, high bit: sound is delayable */ byte xxx chunk -1: marks end of track chunk -2: marks start of loop next chunk starts immediately chunk -3: marks end of loop loop to last chunk -2 chunk -4: reset sound system next chunk starts immediately chunk 0: music /* must be the first chunk! */ int16 mplex int16 chan1_data (offset from beggining of pcjr resource) int16 chan2_data int16 chan3_data int16 chan4_data channel data: int16 a incr_volume_delta (attack) int16 b decr_volume_delta (decay) int16 c int16 d int16 e n times: int16 notelen/4 int16 freq (0: inter note pause) int16 endmarker (-1: goto next chunk, -2: repeat this chunk) abcde describe hull curve: ^ / \b a/ -------\ / | \ / c \ d/(e+1) / | \ / - \--------- | 1 |2| 3 | 4 | 5 phase 4/5 are only used, when a pause occurs (freq=0). chunk 1: (freq up/down) (must be first chunk) int16 mplex int16 offset_2nd_channel_data (-1: not present) int16 first channel several times: int16 start_value int16 delta int16 length int16 -1 2nd_channel_data: int16 first channel several times: int16 start_value int16 delta int16 length int16 -1 chunk 2: (same as speaker chunk 2) int16 start_mplex int16 dest_mplex int16 mplex_delta /* speaker output is toggled on any interrupt */ chunk 3: (generate noise) int16 mplex int16 noise_reg if ((noise_reg & 3) == 3) int16 noise_period (channel 2) int16 noise_volume int16 num_noise_vol_delta int16 noise_vol_deltas int16 ... sounds in demo levels: 6 8 9 11 12 sound 13! chan1 = 0xe7 chan2 = 0xc0 000000: 01 00 a8 61 20 00 e7 00 0f 00 ff ff 0f 00 0f 00 |...a ...........| 000010: 00 00 32 00 00 00 01 00 0f 00 ff ff ff ff c0 00 |..2.............| 000020: 2c 01 f6 ff 0f 00 e8 03 00 00 32 00 64 00 0a 00 |,.........2.d...| 000030: 0f 00 ff ff ff ff 21 22 23 24 25 (telephone) 26 28 WARNING: Unimplemented PCjr chunk in sound 32:! chan1 = 0x80 chan2 = 0xa0 000000: 01 00 40 1f 1c 00 80 00 32 00 0a 00 46 00 ee 02 |..@.....2...F...| 000010: f6 ff 46 00 ff ff fd ff a0 00 ee 02 f6 ff 46 00 |..F...........F.| 000020: 32 00 0a 00 46 00 ff ff fd ff WARNING: Unimplemented PCjr chunk in sound 33:! chan1 = 0x80 chan2 = 0xa0 000000: 01 00 40 1f 1c 00 80 00 32 00 0a 00 46 00 ee 02 |..@.....2...F...| 000010: f6 ff 46 00 ff ff fd ff a0 00 ee 02 f6 ff 46 00 |..F...........F.| 000020: 32 00 0a 00 46 00 ff ff fd ff 36 38 39 42 44 46 50 54 56 57 58 63 70 71 72 73 74 75