diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/i_oplmusic.c | 178 |
1 files changed, 12 insertions, 166 deletions
diff --git a/src/i_oplmusic.c b/src/i_oplmusic.c index dd62076d..e9e722e4 100644 --- a/src/i_oplmusic.c +++ b/src/i_oplmusic.c @@ -326,149 +326,11 @@ static unsigned int num_tracks; static unsigned int running_tracks = 0; static boolean song_looping; -// In the initialisation stage, register writes are spaced by reading -// from the register port (0). After initialisation, spacing is -// peformed by reading from the data port instead. I have no idea -// why. - -static boolean init_stage_reg_writes = false; - // Configuration file variable, containing the port number for the // adlib chip. int opl_io_port = 0x388; -static unsigned int GetStatus(void) -{ - return OPL_ReadPort(OPL_REGISTER_PORT); -} - -// Write an OPL register value - -static void WriteRegister(int reg, int value) -{ - int i; - - OPL_WritePort(OPL_REGISTER_PORT, reg); - - // For timing, read the register port six times after writing the - // register number to cause the appropriate delay - - for (i=0; i<6; ++i) - { - // An oddity of the Doom OPL code: at startup initialisation, - // the spacing here is performed by reading from the register - // port; after initialisation, the data port is read, instead. - - if (init_stage_reg_writes) - { - OPL_ReadPort(OPL_REGISTER_PORT); - } - else - { - OPL_ReadPort(OPL_DATA_PORT); - } - } - - OPL_WritePort(OPL_DATA_PORT, value); - - // Read the register port 25 times after writing the value to - // cause the appropriate delay - - for (i=0; i<24; ++i) - { - GetStatus(); - } -} - -// Detect the presence of an OPL chip - -static boolean DetectOPL(void) -{ - int result1, result2; - int i; - - // Reset both timers: - WriteRegister(OPL_REG_TIMER_CTRL, 0x60); - - // Enable interrupts: - WriteRegister(OPL_REG_TIMER_CTRL, 0x80); - - // Read status - result1 = GetStatus(); - - // Set timer: - WriteRegister(OPL_REG_TIMER1, 0xff); - - // Start timer 1: - WriteRegister(OPL_REG_TIMER_CTRL, 0x21); - - // Wait for 80 microseconds - // This is how Doom does it: - - for (i=0; i<200; ++i) - { - GetStatus(); - } - - OPL_Delay(1); - - // Read status - result2 = GetStatus(); - - // Reset both timers: - WriteRegister(OPL_REG_TIMER_CTRL, 0x60); - - // Enable interrupts: - WriteRegister(OPL_REG_TIMER_CTRL, 0x80); - - return (result1 & 0xe0) == 0x00 - && (result2 & 0xe0) == 0xc0; -} - -// Initialise registers on startup - -static void InitRegisters(void) -{ - int r; - - // Initialise level registers - - for (r=OPL_REGS_LEVEL; r <= OPL_REGS_LEVEL + OPL_NUM_OPERATORS; ++r) - { - WriteRegister(r, 0x3f); - } - - // Initialise other registers - // These two loops write to registers that actually don't exist, - // but this is what Doom does ... - // Similarly, the <= is also intenational. - - for (r=OPL_REGS_ATTACK; r <= OPL_REGS_WAVEFORM + OPL_NUM_OPERATORS; ++r) - { - WriteRegister(r, 0x00); - } - - // More registers ... - - for (r=1; r < OPL_REGS_LEVEL; ++r) - { - WriteRegister(r, 0x00); - } - - // Re-initialise the low registers: - - // Reset both timers and enable interrupts: - WriteRegister(OPL_REG_TIMER_CTRL, 0x60); - WriteRegister(OPL_REG_TIMER_CTRL, 0x80); - - // "Allow FM chips to control the waveform of each operator": - WriteRegister(OPL_REG_WAVEFORM_ENABLE, 0x20); - - // Keyboard split point on (?) - WriteRegister(OPL_REG_FM_MODE, 0x40); -} - // Load instrument table from GENMIDI lump: static boolean LoadInstrumentTable(void) @@ -584,11 +446,11 @@ static void LoadOperatorData(int operator, genmidi_op_t *data, level |= 0x3f; } - WriteRegister(OPL_REGS_LEVEL + operator, level); - WriteRegister(OPL_REGS_TREMOLO + operator, data->tremolo); - WriteRegister(OPL_REGS_ATTACK + operator, data->attack); - WriteRegister(OPL_REGS_SUSTAIN + operator, data->sustain); - WriteRegister(OPL_REGS_WAVEFORM + operator, data->waveform); + OPL_WriteRegister(OPL_REGS_LEVEL + operator, level); + OPL_WriteRegister(OPL_REGS_TREMOLO + operator, data->tremolo); + OPL_WriteRegister(OPL_REGS_ATTACK + operator, data->attack); + OPL_WriteRegister(OPL_REGS_SUSTAIN + operator, data->sustain); + OPL_WriteRegister(OPL_REGS_WAVEFORM + operator, data->waveform); } // Set the instrument for a particular voice. @@ -629,8 +491,8 @@ static void SetVoiceInstrument(opl_voice_t *voice, // two operators. Turn on bits in the upper nybble; I think this // is for OPL3, where it turns on channel A/B. - WriteRegister(OPL_REGS_FEEDBACK + voice->index, - data->feedback | 0x30); + OPL_WriteRegister(OPL_REGS_FEEDBACK + voice->index, + data->feedback | 0x30); // Hack to force a volume update. @@ -669,7 +531,7 @@ static void SetVoiceVolume(opl_voice_t *voice, unsigned int volume) { voice->reg_volume = reg_volume; - WriteRegister(OPL_REGS_LEVEL + voice->op2, reg_volume); + OPL_WriteRegister(OPL_REGS_LEVEL + voice->op2, reg_volume); // If we are using non-modulated feedback mode, we must set the // volume for both voices. @@ -679,7 +541,7 @@ static void SetVoiceVolume(opl_voice_t *voice, unsigned int volume) if ((opl_voice->feedback & 0x01) != 0) { - WriteRegister(OPL_REGS_LEVEL + voice->op1, reg_volume); + OPL_WriteRegister(OPL_REGS_LEVEL + voice->op1, reg_volume); } } } @@ -731,17 +593,7 @@ static boolean I_OPL_InitMusic(void) { if (!OPL_Init(opl_io_port)) { - return false; - } - - init_stage_reg_writes = true; - - // Doom does the detection sequence twice, for some reason: - - if (!DetectOPL() || !DetectOPL()) - { printf("Dude. The Adlib isn't responding.\n"); - OPL_Shutdown(); return false; } @@ -753,14 +605,8 @@ static boolean I_OPL_InitMusic(void) return false; } - InitRegisters(); InitVoices(); - // Now that initialisation has finished, switch the - // register writing mode: - - init_stage_reg_writes = false; - music_initialised = true; return true; @@ -789,7 +635,7 @@ static void I_OPL_SetMusicVolume(int volume) static void VoiceKeyOff(opl_voice_t *voice) { - WriteRegister(OPL_REGS_FREQ_2 + voice->index, voice->freq >> 8); + OPL_WriteRegister(OPL_REGS_FREQ_2 + voice->index, voice->freq >> 8); } // Get the frequency that we should be using for a voice. @@ -947,8 +793,8 @@ static void UpdateVoiceFrequency(opl_voice_t *voice) if (voice->freq != freq) { - WriteRegister(OPL_REGS_FREQ_1 + voice->index, freq & 0xff); - WriteRegister(OPL_REGS_FREQ_2 + voice->index, (freq >> 8) | 0x20); + OPL_WriteRegister(OPL_REGS_FREQ_1 + voice->index, freq & 0xff); + OPL_WriteRegister(OPL_REGS_FREQ_2 + voice->index, (freq >> 8) | 0x20); voice->freq = freq; } |