Index: engines/simon/simon.cpp
===================================================================
--- engines/simon/simon.cpp	(revision 22950)
+++ engines/simon/simon.cpp	(working copy)
@@ -450,6 +450,9 @@
 		if (_native_mt32) {
 			driver->property(MidiDriver::PROP_CHANNEL_MASK, 0x03FE);
 		}
+		if (midiDriver == MD_ADLIB) {
+			midi.property(PROP_ADLIB, 1);
+		}
 	}
 
 	midi.mapMT32toGM (getGameType() == GType_SIMON1 && !_native_mt32);
Index: engines/simon/midi.h
===================================================================
--- engines/simon/midi.h	(revision 22950)
+++ engines/simon/midi.h	(working copy)
@@ -34,6 +34,10 @@
 
 namespace Simon {
 
+enum {
+	PROP_ADLIB
+};
+
 struct MusicInfo {
 	MidiParser *parser;
 	byte *data;
@@ -59,6 +63,7 @@
 	MidiDriver *_driver;
 	bool _map_mt32_to_gm;
 	bool _passThrough;
+	bool _adlib;
 
 	MusicInfo _music;
 	MusicInfo _sfx;
@@ -74,11 +79,15 @@
 	byte _queuedTrack;
 	bool _loopQueuedTrack;
 
+	byte *_adlibPatches;
+
 protected:
 	static void onTimer(void *data);
 	void clearConstructs();
 	void clearConstructs(MusicInfo &info);
 	void resetVolumeTable();
+	void loadAdlibPatches();
+	void unloadAdlibPatches();
 
 public:
 	bool _enable_sfx;
@@ -110,6 +119,7 @@
 	int open();
 	void close();
 	void send(uint32 b);
+	uint32 property(int prop, uint32 param);
 
 	void metaEvent(byte type, byte *data, uint16 length);
 	void setPassThrough(bool b)		{ _passThrough = b; }
Index: engines/simon/midi.cpp
===================================================================
--- engines/simon/midi.cpp	(revision 22950)
+++ engines/simon/midi.cpp	(working copy)
@@ -46,6 +46,9 @@
 	_map_mt32_to_gm = false;
 	_passThrough = false;
 
+	_adlib = false;
+	_adlibPatches = NULL;
+
 	_enable_sfx = true;
 	_current = 0;
 
@@ -84,6 +87,7 @@
 		_driver->close();
 	_driver = NULL;
 	clearConstructs();
+	unloadAdlibPatches();
 //	_system->unlockMutex(_mutex);
 }
 
@@ -103,8 +107,10 @@
 		_current->volume[channel] = volume;
 		volume = volume * _masterVolume / 255;
 		b = (b & 0xFF00FFFF) | (volume << 16);
-	} else if ((b & 0xF0) == 0xC0 && _map_mt32_to_gm) {
-		b = (b & 0xFFFF00FF) | (MidiDriver::_mt32ToGm[(b >> 8) & 0xFF] << 8);
+	} else if ((b & 0xF0) == 0xC0) {
+		if (_map_mt32_to_gm && (!_adlib || !_adlibPatches)) {
+			b = (b & 0xFFFF00FF) | (MidiDriver::_mt32ToGm[(b >> 8) & 0xFF] << 8);
+		}
 	} else if ((b & 0xFFF0) == 0x007BB0) {
 		// Only respond to an All Notes Off if this channel
 		// has already been allocated.
@@ -129,7 +135,14 @@
 	if (_current->channel[channel]) {
 		if (channel == 9)
 			_current->channel[9]->volume(_current->volume[9] * _masterVolume / 255);
-		_current->channel[channel]->send(b);
+		if ((b & 0xF0) == 0xC0 && _adlib && _adlibPatches) {
+			// NOTE: In the percussion channel, this function is a
+			//       no-op. Any percussion instruments you hear may
+			//       be the stock ones from adlib.cpp.
+			_driver->sysEx_customInstrument(_current->channel[channel]->getNumber(), 'ADL ', _adlibPatches + 30 * ((b >> 8) & 0xFF));
+		} else {
+			_current->channel[channel]->send(b);
+		}
 		if ((b & 0xFFF0) == 0x79B0) {
 			// We have received a "Reset All Controllers" message
 			// and passed it on to the MIDI driver. This may or may
@@ -142,6 +155,19 @@
 	}
 }
 
+uint32 MidiPlayer::property(int prop, uint32 param) {
+	if (prop == PROP_ADLIB) {
+		uint32 ret = _adlib ? 1 : 0;
+		_adlib = (param != 0);
+		if (_adlib)
+			loadAdlibPatches();
+		else
+			unloadAdlibPatches();
+		return ret;
+	}
+	return MidiDriver::property(prop, param);
+}
+
 void MidiPlayer::metaEvent(byte type, byte *data, uint16 length) {
 	// Only thing we care about is End of Track.
 	if (!_current || type != 0x2F) {
@@ -352,6 +378,50 @@
 	}
 }
 
+void MidiPlayer::loadAdlibPatches() {
+	if (!_adlib)
+		return;
+
+	Common::File ibk;
+
+	if (!ibk.open("mt_fm.ibk"))
+		return;
+
+	if (ibk.readUint32BE() == 0x49424b1a) {
+		_adlibPatches = new byte[128 * 30];
+		byte *ptr = _adlibPatches;
+
+		memset(_adlibPatches, 0, 128 * 30);
+
+		for (int i = 0; i < 128; i++) {
+			byte instr[16];
+
+			ibk.read(instr, 16);
+
+			ptr[0] = instr[0];   // Modulator Sound Characteristics
+			ptr[1] = instr[2];   // Modulator Scaling/Output Level
+			ptr[2] = ~instr[4];  // Modulator Attack/Decay
+			ptr[3] = ~instr[6];  // Modulator Sustain/Release
+			ptr[4] = instr[8];   // Modulator Wave Select
+			ptr[5] = instr[1];   // Carrier Sound Characteristics
+			ptr[6] = instr[3];   // Carrier Scaling/Output Level
+			ptr[7] = ~instr[5];  // Carrier Attack/Delay
+			ptr[8] = ~instr[7];  // Carrier Sustain/Release
+			ptr[9] = instr[9];   // Carrier Wave Select
+			ptr[10] = instr[10]; // Feedback/Connection
+
+			// The remaining six bytes are reserved for future use
+
+			ptr += 30;
+		}
+	}
+}
+
+void MidiPlayer::unloadAdlibPatches() {
+	delete[] _adlibPatches;
+	_adlibPatches = NULL;
+}
+
 static int simon1_gmf_size[] = {
 	8900, 12166, 2848, 3442, 4034, 4508, 7064, 9730, 6014, 4742, 3138,
 	6570, 5384, 8909, 6457, 16321, 2742, 8968, 4804, 8442, 7717,
