[Scummvm-cvs-logs] SF.net SVN: scummvm: [21081] scummvm/trunk/engines/kyra/sound_adlib.cpp

eriktorbjorn at users.sourceforge.net eriktorbjorn at users.sourceforge.net
Sat Mar 4 14:33:01 CET 2006


Revision: 21081
Author:   eriktorbjorn
Date:     2006-03-04 12:27:51 -0800 (Sat, 04 Mar 2006)
ViewCVS:  http://svn.sourceforge.net/scummvm?rev=21081&view=rev

Log Message:
-----------
Cleanup: output0x388(0xABCD) is now writeOPL(0xAB, 0xCD), which is slightly
more easy to read.

Modified Paths:
--------------
    scummvm/trunk/engines/kyra/sound_adlib.cpp
Modified: scummvm/trunk/engines/kyra/sound_adlib.cpp
===================================================================
--- scummvm/trunk/engines/kyra/sound_adlib.cpp	2006-03-04 19:35:38 UTC (rev 21080)
+++ scummvm/trunk/engines/kyra/sound_adlib.cpp	2006-03-04 20:27:51 UTC (rev 21081)
@@ -148,8 +148,7 @@
 	void stateCallback2_1(OutputState& state);
 
 	void resetAdlibState();
-	void output0x388(uint16 word);
-	void waitLoops(int count);
+	void writeOPL(byte reg, byte val);
 	void initTable(OutputState &table);
 	void unkOutput1(OutputState &table);
 	void unkOutput2(uint8 num);
@@ -613,41 +612,35 @@
 void AdlibDriver::resetAdlibState() {
 	debugC(9, kDebugLevelSound, "resetAdlibState()");
 	_unk6 = 0x1234;
-	output0x388(0x0120);
-	output0x388(0x0800);
-	output0x388(0xBD00);
+
+	// Authorize the control of the waveforms
+	writeOPL(0x01, 0x20);
+
+	// Select FM music mode
+	writeOPL(0x08, 0x00);
+
+	// I would guess the main purpose of this is to turn off the rhythm,
+	// thus allowing us to use 9 melodic voices instead of 6.
+	writeOPL(0xBD, 0x00);
+
 	int loop = 10;
 	while (loop--) {
 		if (loop != 9) {
-			output0x388(((_outputTable[loop] + 0x40) << 8) | 0x3F);
-			output0x388(((_outputTable[loop] + 0x43) << 8) | 0x3F);
+			// Silence the channel
+			writeOPL(0x40 + _outputTable[loop], 0x3F);
+			writeOPL(0x43 + _outputTable[loop], 0x3F);
 		}
 		initTable(_outputTables[loop]);
 	}
 }
 
-void AdlibDriver::output0x388(uint16 word) {
-	// 0x388 - Adress/Status port (R/W)
-	// 0x389 - Data port          (W/O)
+// Old calling style: output0x388(0xABCD)
+// New calling style: writeOPL(0xAB, 0xCD)
 
-	// The "wait loops" are there to allow the hardware enough time to
-	// register that it has been written to. I don't think we do that in
-	// any of the other ScummVM Adlib players, so it might not be
-	// necessary. On the other hand, it shouldn't do any harm either, so
-	// let's keep it for now. Until the music works properly, at least.
-
-	OPLWrite(_adlib, 0x388, (word >> 8) & 0xFF);
-	waitLoops(4);
-	OPLWrite(_adlib, 0x389, word & 0xFF);
-	waitLoops(23);
+void AdlibDriver::writeOPL(byte reg, byte val) {
+	OPLWriteReg(_adlib, reg, val);
 }
 
-void AdlibDriver::waitLoops(int count) {
-	while (count--) {
-		OPLRead(_adlib, 0x388);
-	}
-}
-
 void AdlibDriver::initTable(OutputState &table) {
 	debugC(9, kDebugLevelSound, "initTable(%d)", &table - _outputTables);
 	memset(&table.dataptr, 0, sizeof(OutputState) - ((char*)&table.dataptr - (char*)&table));
@@ -667,14 +660,11 @@
 	if (_unk4 && _curTable >= 6)
 		return;
 
-	// Octave / F-Number / Key-On
-	uint16 output = (_curTable + 0xB0) << 8;
-
 	// This means the "Key On" bit will always be 0
 	table.unkOutputValue1 &= 0xDF;
 
-	output |= table.unkOutputValue1;
-	output0x388(output);
+	// Octave / F-Number / Key-On
+	writeOPL(0xB0 + _curTable, table.unkOutputValue1);
 }
 
 void AdlibDriver::unkOutput2(uint8 num) {
@@ -686,20 +676,20 @@
 	uint8 value = _outputTable[num];
 
 	// Clear the Attack Rate / Decay Rate for the channel
-	output0x388(((value + 0x60) << 8) | 0xFF);
-	output0x388(((value + 0x63) << 8) | 0xFF);
+	writeOPL(0x60 + value, 0xFF);
+	writeOPL(0x63 + value, 0xFF);
 
 	// Clear the Sustain Level / Release Rate for the channel
-	output0x388(((value + 0x80) << 8) | 0xFF);
-	output0x388(((value + 0x83) << 8) | 0xFF);
+	writeOPL(0x80 + value, 0xFF);
+	writeOPL(0x83 + value, 0xFF);
 
 	// Octave / F-Number / Key-On
 
 	// The purpose of this seems to be to first clear everything, and then
 	// set the octave.
 
-	output0x388(((num + 0xB0) << 8) | 0x00);
-	output0x388(((num + 0xB0) << 8) | 0x20);
+	writeOPL(0xB0 + num, 0x00);
+	writeOPL(0xB0 + num, 0x20);
 }
 
 uint16 AdlibDriver::updateUnk6Value() {
@@ -767,42 +757,42 @@
 	state.unk17 = value & 0xFF;
 
 	// Octave / F-Number / Key-On
-	output0x388(((0xA0 + _curTable) << 8) | state.unk17);
-	output0x388(((0xB0 + _curTable) << 8) | state.unkOutputValue1);
+	writeOPL(0xA0 + _curTable, state.unk17);
+	writeOPL(0xB0 + _curTable, state.unkOutputValue1);
 }
 
 void AdlibDriver::updateAndOutput2(uint8 unk1, uint8 *dataptr, OutputState &state) {
 	debugC(9, kDebugLevelSound, "updateAndOutput2(%d, 0x%X, %d)", unk1, dataptr, &state - _outputTables);
 	// Amplitude Modulation / Vibrato / Envelope Generator Type /
 	// Keyboard Scaling Rate / Modulator Frequency Multiple
-	output0x388(((0x20 + unk1) << 8) | *dataptr++);
-	output0x388(((0x23 + unk1) << 8) | *dataptr++);
+	writeOPL(0x20 + unk1, *dataptr++);
+	writeOPL(0x23 + unk1, *dataptr++);
 
 	uint8 temp = *dataptr++;
 
 	// Feedback / Algorithm
-	output0x388(((0xC0 + _curTable) << 8) | temp);
+	writeOPL(0xC0 + _curTable, temp);
 
 	state.unk23 = temp & 1;
 
 	// Waveform Select
-	output0x388(((0xE0 + unk1) << 8) | *dataptr++);
-	output0x388(((0xE3 + unk1) << 8) | *dataptr++);
+	writeOPL(0xE0 + unk1, *dataptr++);
+	writeOPL(0xE3 + unk1, *dataptr++);
 
 	state.unk24 = *dataptr++;
 	state.unk25 = *dataptr++;
 
 	// Level Key Scaling / Total Level
-	output0x388(((0x40 + unk1) << 8) | calculateLowByte1(state));
-	output0x388(((0x43 + unk1) << 8) | calculateLowByte2(state));
+	writeOPL(0x40 + unk1, calculateLowByte1(state));
+	writeOPL(0x43 + unk1, calculateLowByte2(state));
 
 	// Attack Rate / Decay Rate
-	output0x388(((0x60 + unk1) << 8) | *dataptr++);
-	output0x388(((0x63 + unk1) << 8) | *dataptr++);
+	writeOPL(0x60 + unk1, *dataptr++);
+	writeOPL(0x63 + unk1, *dataptr++);
 
 	// Sustain Level / Release Rate
-	output0x388(((0x80 + unk1) << 8) | *dataptr++);
-	output0x388(((0x83 + unk1) << 8) | *dataptr++);
+	writeOPL(0x80 + unk1, *dataptr++);
+	writeOPL(0x83 + unk1, *dataptr++);
 }
 
 void AdlibDriver::updateAndOutput3(OutputState &state) {
@@ -811,7 +801,7 @@
 	state.unkOutputValue1 |= 0x20;
 
 	// Octave / F-Number / Key-On
-	output0x388(((0xB0 + _curTable) << 8) | state.unkOutputValue1);
+	writeOPL(0xB0 + _curTable, state.unkOutputValue1);
 
 	int8 shift = 9 - state.unk33;
 	uint16 temp = state.unk17 | (state.unkOutputValue1 << 8);
@@ -824,12 +814,12 @@
 	uint8 lowByte = calculateLowByte2(state);
 
 	// Level Key Scaling / Total Level
-	output0x388(((0x43 + _outputTable[_curTable]) << 8) | lowByte);
+	writeOPL(0x43 + _outputTable[_curTable], lowByte);
 	if (state.unk23) {
 		lowByte = calculateLowByte1(state);
 
 		// Level Key Scaling / Total Level
-		output0x388(((0x40 + _outputTable[_curTable]) << 8) | lowByte);
+		writeOPL(0x40 + _outputTable[_curTable], lowByte);
 	}
 }
 
@@ -863,13 +853,14 @@
 	}
 	unk1 &= 0x3FF;
 
-	output0x388(((0xA0 + _curTable) << 8) | (unk1 & 0xFF));
+	writeOPL(0xA0 + _curTable, unk1 & 0xFF);
 	state.unk17 = unk1 & 0xFF;
 
 	uint8 value = unk1 >> 8;
 	value |= (unk2 >> 8) & 0xFF;
 	value |= unk2 & 0xFF;
-	output0x388(((0xB0 + _curTable) << 8) | value);
+
+	writeOPL(0xB0 + _curTable, value);
 	state.unkOutputValue1 = value;
 }
 
@@ -897,8 +888,8 @@
 		state.unkOutputValue1 = (state.unkOutputValue1 & 0xFC) | (temp3 >> 8);
 
 		// Octave / F-Number / Key-On
-		output0x388(((0xA0 + _curTable) << 8) | state.unkOutputValue1);
-		output0x388(((0xB0 + _curTable) << 8) | state.unkOutputValue1);
+		writeOPL(0xA0 + _curTable, state.unkOutputValue1);
+		writeOPL(0xB0 + _curTable, state.unkOutputValue1);
 	}
 }
 
@@ -909,9 +900,7 @@
 		if ((--state.unk21) & 0x80) {
 			state.unk21 = state.unk20;
 		}
-		uint16 value = (state.unk22 + _unkOutputByte1) << 8;
-		value |= (_soundData/*state.dataptr:segment*/ + state.offset)[state.unk21];
-		output0x388(value);
+		writeOPL(state.unk22 + _unkOutputByte1, _soundData[state.offset + state.unk21]);
 	}
 }
 
@@ -1030,7 +1019,7 @@
 }
 
 int AdlibDriver::update_writeAdlib(uint8 *&dataptr, OutputState &state, uint8 value) {
-	output0x388((value << 8) || *dataptr++);
+	writeOPL(value, *dataptr++);
 	return 0;
 }
 
@@ -1217,7 +1206,7 @@
 		_unkOutputByte2 &= 0x7F;
 
 	// The AM Depth bit is set or cleared, the others remain unchanged
-	output0x388(0xBD00 | _unkOutputByte2);
+	writeOPL(0xBD, _unkOutputByte2);
 	return 0;
 }
 
@@ -1228,7 +1217,7 @@
 		_unkOutputByte2 &= 0xBF;
 
 	// The Vibrato Depth bit is set or cleared, the others remain unchanged
-	output0x388(0xBD00 | _unkOutputByte2);
+	writeOPL(0xBD, _unkOutputByte2);
 	return 0;
 }
 
@@ -1251,16 +1240,16 @@
 		uint8 outValue = _outputTable[value];
 
 		// Feedback strength / Connection type
-		output0x388((0xC0 + _curTable) << 8);
+		writeOPL(0xC0 + _curTable, 0x00);
 
 		// Key scaling level / Operator output level
-		output0x388(((0x43 + outValue) << 8) | 0x3F);
+		writeOPL(0x43 + outValue, 0x3F);
 
 		// Sustain Level / Release Rate
-		output0x388(((0x83 + outValue) << 8) | 0xFF);
+		writeOPL(0x83 + outValue, 0xFF);
 
 		// Key On / Octave / Frequency
-		output0x388((0xB0 + _curTable) << 8);
+		writeOPL(0xB0 + _curTable, 0x00);
 	}
 
 	_curTable = tableBackUp;
@@ -1277,10 +1266,10 @@
 	unk2 |= ((state.unkOutputValue1 & 0x20) << 8);
 
 	// Frequency
-	output0x388(((0xA0 + _curTable) << 8) | (unk2 & 0xFF));
+	writeOPL(0xA0 + _curTable, unk2 & 0xFF);
 
 	// Key On / Octave / Frequency
-	output0x388(((0xB0 + _curTable) << 8) | ((unk2 & 0xFF00) >> 8));
+	writeOPL(0xB0 + _curTable, (unk2 & 0xFF00) >> 8);
 
 	return 0;
 }
@@ -1329,10 +1318,10 @@
 	state.unk17 = unk1;
 
 	// Frequency
-	output0x388(((0xA0 + _curTable) << 8) | unk1);
+	writeOPL(0xA0 + _curTable, unk1);
 
 	// Key On / Octave / Frequency
-	output0x388(((0xB0 + _curTable) << 8) | state.unkOutputValue1);
+	writeOPL(0xB0 + _curTable, state.unkOutputValue1);
 
 	return 0;
 }
@@ -1373,7 +1362,7 @@
 	_tablePtr2 = _unkTable2[entry];
 	if (value == 2) {
 		// Frequency
-		output0x388(0xA000 | _tablePtr2[0]);
+		writeOPL(0xA0, _tablePtr2[0]);
 	}
 	return 0;
 }
@@ -1421,16 +1410,16 @@
 	// Octave / F-Number / Key-On for channels 6, 7 and 8
 
 	_outputTables[6].unkOutputValue1 = *ptr++ & 0x2F;
-	output0x388(0xB600 | _outputTables[6].unkOutputValue1);
-	output0x388(0xA600 | *ptr++);
+	writeOPL(0xB6, _outputTables[6].unkOutputValue1);
+	writeOPL(0xA6, *ptr++);
 
 	_outputTables[7].unkOutputValue1 = *ptr++ & 0x2F;
-	output0x388(0xB700 | _outputTables[7].unkOutputValue1);
-	output0x388(0xA700 | *ptr++);
+	writeOPL(0xB7, _outputTables[7].unkOutputValue1);
+	writeOPL(0xA7, *ptr++);
 
 	_outputTables[8].unkOutputValue1 = *ptr++ & 0x2F;
-	output0x388(0xB800 | _outputTables[8].unkOutputValue1);
-	output0x388(0xA800 | *ptr++);
+	writeOPL(0xB8, _outputTables[8].unkOutputValue1);
+	writeOPL(0xA8, *ptr++);
 
 	_unk4 = 0x20;
 
@@ -1441,7 +1430,7 @@
 
 int AdlibDriver::updateCallback49(uint8 *&dataptr, OutputState &state, uint8 value) {
 	// Amplitude Modulation Depth / Vibrato Depth / Rhythm
-	output0x388(0xBD00 | (((value & 0x1F) ^ 0xFF) & _unk4) | 0x20);
+	writeOPL(0xBD, (((value & 0x1F) ^ 0xFF) & _unk4) | 0x20);
 
 	value |= _unk4;
 	_unk4 = value;
@@ -1449,12 +1438,16 @@
 	value |= _unkOutputByte2;
 	value |= 0x20;
 
-	// Could maybe use output0x388() here as well, though perhaps that will
-	// affect timing.
+	// FIXME: This could probably be replaced with writeOPL(0xBD, value),
+	//        but to make it easier to compare the output to DOSbox, write
+	//        directly to the data port and do the probably unnecessary
+	//        delay loop.
 
 	OPLWrite(_adlib, 0x389, value);
-	waitLoops(23);
 
+	for (int i = 0; i < 23;  i++)
+		OPLRead(_adlib, 0x388);
+
 	return 0;
 }
 
@@ -1463,7 +1456,7 @@
 	_unk4 = 0;
 
 	// Amplitude Modulation Depth / Vibrato Depth / Rhythm
-	output0x388(0xBD00 | (value & _unkOutputByte2));
+	writeOPL(0xBD, value & _unkOutputByte2);
 
 	return 0;
 }
@@ -1479,7 +1472,7 @@
 		val += _unkValue12;
 
 		// Channel 2: Level Key Scaling / Total Level
-		output0x388(0x5100 | checkValue(val));
+		writeOPL(0x51, checkValue(val));
 	}
 
 	if (value & 2) {
@@ -1490,7 +1483,7 @@
 		val += _unkValue14;
 
 		// Channel 3: Level Key Scaling / Total Level
-		output0x388(0x5500 | checkValue(val));
+		writeOPL(0x55, checkValue(val));
 	}
 
 	if (value & 4) {
@@ -1501,7 +1494,7 @@
 		val += _unkValue15;
 
 		// Channel 3: Level Key Scaling / Total Level
-		output0x388(0x5200 | checkValue(val));
+		writeOPL(0x52, checkValue(val));
 	}
 
 	if (value & 8) {
@@ -1512,7 +1505,7 @@
 		val += _unkValue18;
 
 		// Channel 2: Level Key Scaling / Total Level
-		output0x388(0x5400 | checkValue(val));
+		writeOPL(0x54, checkValue(val));
 	}
 
 	if (value & 16) {
@@ -1523,7 +1516,7 @@
 		val += _unkValue20;
 
 		// Channel 1: Level Key Scaling / Total Level
-		output0x388(0x5300 | checkValue(val));
+		writeOPL(0x53, checkValue(val));
 	}
 
 	return 0;
@@ -1539,7 +1532,7 @@
 		val += _unkValue12;
 
 		// Channel 2: Level Key Scaling / Total Level
-		output0x388(0x5100 | checkValue(val));
+		writeOPL(0x51, checkValue(val));
 	}
 
 	if (value & 2) {
@@ -1549,7 +1542,7 @@
 		val += _unkValue14;
 
 		// Channel 3: Level Key Scaling / Total Level
-		output0x388(0x5500 | checkValue(val));
+		writeOPL(0x55, checkValue(val));
 	}
 
 	if (value & 4) {
@@ -1559,7 +1552,7 @@
 		val += _unkValue15;
 
 		// Channel 3: Level Key Scaling / Total Level
-		output0x388(0x5200 | checkValue(val));
+		writeOPL(0x52, checkValue(val));
 	}
 
 	if (value & 8) {
@@ -1569,7 +1562,7 @@
 		val += _unkValue18;
 
 		// Channel 2: Level Key Scaling / Total Level
-		output0x388(0x5400 | checkValue(val));
+		writeOPL(0x54, checkValue(val));
 	}
 
 	if (value & 16) {
@@ -1579,7 +1572,7 @@
 		val += _unkValue20;
 
 		// Channel 1: Level Key Scaling / Total Level
-		output0x388(0x5300 | checkValue(val));
+		writeOPL(0x53, checkValue(val));
 	}
 
 	return 0;
@@ -1595,7 +1588,7 @@
 		val += _unkValue12;
 
 		// Channel 2: Level Key Scaling / Total Level
-		output0x388(0x5100 | checkValue(val));
+		writeOPL(0x51, checkValue(val));
 	}
 
 	if (value & 2) {
@@ -1605,7 +1598,7 @@
 		val += _unkValue14;
 
 		// Channel 3: Level Key Scaling / Total Level
-		output0x388(0x5500 | checkValue(val));
+		writeOPL(0x55, checkValue(val));
 	}
 
 	if (value & 4) {
@@ -1615,7 +1608,7 @@
 		val += _unkValue15;
 
 		// Channel 3: Level Key Scaling / Total Level
-		output0x388(0x5200 | checkValue(val));
+		writeOPL(0x52, checkValue(val));
 	}
 
 	if (value & 8) {
@@ -1625,7 +1618,7 @@
 		val += _unkValue18;
 
 		// Channel 2: Level Key Scaling / Total Level
-		output0x388(0x5400 | checkValue(val));
+		writeOPL(0x54, checkValue(val));
 	}
 
 	if (value & 16) {
@@ -1635,7 +1628,7 @@
 		val += _unkValue20;
 
 		// Channel 1: Level Key Scaling / Total Level
-		output0x388(0x5300 | checkValue(val));
+		writeOPL(0x53, checkValue(val));
 	}
 
 	return 0;







More information about the Scummvm-git-logs mailing list