AdPlug
Newest releases:
Core library2.3.3
AdPlug/Winamp1.8.2
AdPlay/DOS1.6a
AdPlay/UNIX1.8.1
AdPlug/XMMS1.2
libbinio1.5
Main
News
Download
Extras
Library

GitHub Project Page
GitHub Logo

AdLib file formats reference library entry:

Legend:

  • A: The file format is already (partly) supported by AdPlug.
  • D: File format documentation/specification is available.
  • E: Editor software is available.
  • P: Player software is available.
  • M: Test music files are available.
  • S: Source code is available.

Palladix Sound System

.PLX
A    M 
Download

This music format is used in Logical game by Rainbow Arts Software, as well as a few others of the time.

Here is a description of the file format, as reverse-engineered from the Logical game:

Header
------
Bytes 0-2: 'PLX' header

Byte 3: Bottom bit selects rhythm mode (on if set). All other bits MBZ.
If bigger than 2, it seems to bail out.

Byte 4: Scale factor for timer info. Result = Timer * (scale_factor * 64)

Bytes 5-6 (WORD): Timer info (programmed to PIT via OUT 43h, 36h and then OUT 40h, low byte, OUT 40h, high byte)

Bytes 7-16: Array of 9 WORDS: Per-channel note data offset pointers from beginning of file
	If offset pointer is 0, skip this channel

Bytes 17...: Instruments

Instruments
-----------
Byte 0: AdLib operator data for index base C0h. Change index from base, according to channel number (see OPL2 manual).
Byte 1: ? (1h in my first investigation)
Bytes 2..6: AdLib modulator data for index base 20h, 40h, 60h, 80h, E0h.
Bytes 7..11: AdLib carrier data for index base 23h, 43h, 63h, 83h, E3h.

Per-channel note data
---------------------
BYTE: Contains flags
	Bit 0: Set instrument
		Load instrument to AdLib operators from file offset, specified in next WORD
	Bit 1: Set volume
		load following BYTE, store in chan_init[channel#], and in 43h + channel# (plus other stuff, depending on whether Algorithm is 0 for this channel)
	Bit 2: Key off
		Rewrite frequency block (B0h + channel#) without "key on" bit
	Bit 3: Set note (exclusive with "set frequency")
		Load next BYTE, which is the note# (must be between 0..95). Look up resulting frequency in array.
		AX = Get state of both frequency registers (A0 and B0 + chan#)
	Bit 4: Set frequency (exclusive with "set note")
		Load following WORD and set directly into both frequency registers
	Bit 5: Key on
		If "key on" is set, we set the "key on" bit for the channel
	Bit 6: Set global tempo
		Tempo loaded from next WORD and stored in timer
	Bit 7: Skip. All other bits MBZ (BYTE = 80h)

If BYTE = 0h, then this channel resets (restart at pattern offset 0, key off)

Notes
-----
On init, the playroutine:
 * Sets WAVE SELECT ENABLE in OPL2 (index 1, value 20h)
 * Resets all AdLib registers according to the data in
   opl2_init_regs.bin (found in plx.cpp in AdPlug source tree)
   * Byte x at offset y indicates that value x should be written into AdLib at index y, unless x == FFh, in which case we skip it

* Sets rhythm mode according to Byte 3.

* Writes 3F to all AdLib operators.

* Sets up timer according to timer info and scale factor

* Starts playing song in interrupt handler
  For all active channels:
    Read per-channel note data
      Reads the flag byte, processes flags from bottom to top, reading additional BYTEs and WORDs, depending on flags
    Read BYTE that indicates how many pattern positions to skip

The archive contains test music files, ripped from the Logical game.

Last modified on 2024-12-24 23:21:37 +0000
Copyright © 2001 - 2015 Simon Peter