foxygit / doom Log in
commit 90fd85b32dd85884fb9a9cf0a7063c4509147d40
Author:     Simon Howard <fraggle@gmail.com>
AuthorDate: Thu Mar 12 18:50:15 2009 +0000
Commit:     Simon Howard <fraggle@gmail.com>
CommitDate: Thu Mar 12 18:50:15 2009 +0000

    Read from register port when doing register writes during startup phase;
    afterwards, read from the data port.

    Subversion-branch: /branches/opl-branch
    Subversion-revision: 1464
---
 src/i_oplmusic.c | 27 ++++++++++++++++++++++++++-
 1 file changed, 26 insertions(+), 1 deletion(-)

diff --git a/src/i_oplmusic.c b/src/i_oplmusic.c
index baf17bd6..0543be2e 100644
--- a/src/i_oplmusic.c
+++ b/src/i_oplmusic.c
@@ -116,6 +116,13 @@ static genmidi_instr_t *percussion_instrs;
 static opl_voice_t voices[OPL_NUM_VOICES];
 static opl_voice_t *voice_free_list;

+// 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.

@@ -139,7 +146,18 @@ static void WriteRegister(int reg, int value)

     for (i=0; i<6; ++i)
     {
-        GetStatus();
+        // 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);
@@ -393,6 +411,8 @@ static boolean I_OPL_InitMusic(void)
         return false;
     }

+    init_stage_reg_writes = true;
+
     // Doom does the detection sequence twice, for some reason:

     if (!DetectOPL() || !DetectOPL())
@@ -413,6 +433,11 @@ static boolean I_OPL_InitMusic(void)
     InitRegisters();
     InitVoices();

+    // Now that initialisation has finished, switch the
+    // register writing mode:
+
+    init_stage_reg_writes = false;
+
 #ifdef TEST
     {
         opl_voice_t *voice;