]> Shamusworld >> Repos - virtualjaguar/commitdiff
Initial stab at getting the DSP to run in the host audio IRQ. Needs testing.
authorShamus Hammons <jlhamm@acm.org>
Tue, 1 May 2012 12:07:31 +0000 (12:07 +0000)
committerShamus Hammons <jlhamm@acm.org>
Tue, 1 May 2012 12:07:31 +0000 (12:07 +0000)
src/dac.cpp
src/dac.h
src/dsp.cpp
src/dsp.h
src/event.cpp
src/event.h
src/gui/mainwin.cpp
src/jaguar.cpp
src/jerry.cpp
src/memory.cpp

index 983680791fccefe73613246120633f4bf8543e95..be6c3aed9e314853a679c13ba1ddc6720fcf2047 100644 (file)
 #include "dac.h"
 
 #include "SDL.h"
-//#include "gui.h"
+#include "cdrom.h"
+#include "dsp.h"
+#include "event.h"
+#include "jerry.h"
 #include "jaguar.h"
 #include "log.h"
 #include "m68k.h"
 //#include "memory.h"
 #include "settings.h"
 
+
 //#define DEBUG_DAC
 
-#define BUFFER_SIZE            0x10000                                         // Make the DAC buffers 64K x 16 bits
+#define BUFFER_SIZE                    0x10000                         // Make the DAC buffers 64K x 16 bits
+#define DAC_AUDIO_RATE         48000                           // Set the audio rate to 48 KHz
 
 // Jaguar memory locations
 
@@ -72,7 +77,7 @@
 
 // Global variables
 
-//uint16 lrxd, rrxd;                                                                   // I2S ports (into Jaguar)
+//uint16 lrxd, rrxd;                                                   // I2S ports (into Jaguar)
 
 // Local variables
 
@@ -84,12 +89,15 @@ static bool SDLSoundInitialized;
 // endian when looking at the sample buffer, i.e., no need to worry about it.
 
 static uint16 DACBuffer[BUFFER_SIZE];
-static uint8 SCLKFrequencyDivider = 19;                                // Default is roughly 22 KHz (20774 Hz in NTSC mode)
+static uint8 SCLKFrequencyDivider = 19;                        // Default is roughly 22 KHz (20774 Hz in NTSC mode)
 /*static*/ uint16 serialMode = 0;
 
 // Private function prototypes
 
 void SDLSoundCallback(void * userdata, Uint8 * buffer, int length);
+void SDLSoundCallbackNew(void * userdata, Uint8 * buffer, int length);
+void DSPSampleCallback(void);
+
 
 //
 // Initialize the SDL sound system
@@ -104,6 +112,13 @@ void DACInit(void)
                return;
        }
 
+#ifdef NEW_DAC_CODE
+       desired.freq = DAC_AUDIO_RATE;
+       desired.format = AUDIO_S16SYS;
+       desired.channels = 2;
+       desired.samples = 2048;
+       desired.callback = SDLSoundCallbackNew;
+#else
 //     memory_malloc_secure((void **)&DACBuffer, BUFFER_SIZE * sizeof(uint16), "DAC buffer");
 //     DACBuffer = (uint16 *)memory_malloc(BUFFER_SIZE * sizeof(uint16), "DAC buffer");
 
@@ -113,6 +128,7 @@ void DACInit(void)
 //     desired.samples = 4096;                                                 // Let's try a 4K buffer (can always go lower)
        desired.samples = 2048;                                                 // Let's try a 2K buffer (can always go lower)
        desired.callback = SDLSoundCallback;
+#endif
 
        if (SDL_OpenAudio(&desired, NULL) < 0)                  // NULL means SDL guarantees what we want
                WriteLog("DAC: Failed to initialize SDL sound...\n");
@@ -120,19 +136,28 @@ void DACInit(void)
        {
                SDLSoundInitialized = true;
                DACReset();
-               SDL_PauseAudio(false);                                                  // Start playback!
-               WriteLog("DAC: Successfully initialized.\n");
+               SDL_PauseAudio(false);                                          // Start playback!
+               WriteLog("DAC: Successfully initialized. Sample rate: %u\n", desired.freq);
        }
+
+       ltxd = lrxd = desired.silence;
+
+       uint32_t riscClockRate = (vjs.hardwareTypeNTSC ? RISC_CLOCK_RATE_NTSC : RISC_CLOCK_RATE_PAL);
+       uint32_t cyclesPerSample = riscClockRate / DAC_AUDIO_RATE;
+       WriteLog("DAC: RISC clock = %u, cyclesPerSample = %u\n", riscClockRate, cyclesPerSample);
 }
 
+
 //
 // Reset the sound buffer FIFOs
 //
 void DACReset(void)
 {
        LeftFIFOHeadPtr = LeftFIFOTailPtr = 0, RightFIFOHeadPtr = RightFIFOTailPtr = 1;
+       ltxd = lrxd = desired.silence;
 }
 
+
 //
 // Close down the SDL sound subsystem
 //
@@ -162,6 +187,138 @@ void DACDone(void)
 // SDL callback routine to fill audio buffer
 //
 // Note: The samples are packed in the buffer in 16 bit left/16 bit right pairs.
+//       Also, length is the length of the buffer in BYTES
+//
+//static double timePerSample = 0;
+static Uint8 * sampleBuffer;
+static int bufferIndex = 0;
+static int numberOfSamples = 0;
+static bool bufferDone = false;
+void SDLSoundCallbackNew(void * userdata, Uint8 * buffer, int length)
+{
+       // 1st, check to see if the DSP is running. If not, fill the buffer with L/RXTD and exit.
+
+       if (!DSPIsRunning())
+       {
+               for(int i=0; i<(length/2); i+=2)
+               {
+                       ((uint16_t *)buffer)[i + 0] = ltxd;
+                       ((uint16_t *)buffer)[i + 1] = rtxd;
+               }
+
+               return;
+       }
+
+       // The length of time we're dealing with here is 1/48000 s, so we multiply this
+       // by the number of cycles per second to get the number of cycles for one sample.
+       uint32_t riscClockRate = (vjs.hardwareTypeNTSC ? RISC_CLOCK_RATE_NTSC : RISC_CLOCK_RATE_PAL);
+       uint32_t cyclesPerSample = riscClockRate / DAC_AUDIO_RATE;
+       // This is the length of time
+//     timePerSample = (1000000.0 / (double)riscClockRate) * ();
+
+       // Now, run the DSP for that length of time for each sample we need to make
+
+#if 0
+       for(int i=0; i<(length/2); i+=2)
+       {
+//This stuff is from the old Jaguar execute loop. New stuff is timer based...
+//which means we need to figure that crap out, and how to make it work here.
+//Seems like we need two separate timing queues. Tho not sure how to make that work here...
+//Maybe like the "frameDone" in JaguarExecuteNew() in jaguar.cpp?
+//             JERRYExecPIT(cyclesPerSample);
+//             JERRYI2SExec(cyclesPerSample);
+//             BUTCHExec(cyclesPerSample);
+
+               if (vjs.DSPEnabled)
+               {
+                       if (vjs.usePipelinedDSP)
+                               DSPExecP2(cyclesPerSample);
+                       else
+                               DSPExec(cyclesPerSample);
+               }
+
+               ((uint16_t *)buffer)[i + 0] = ltxd;
+               ((uint16_t *)buffer)[i + 1] = rtxd;
+       }
+#else
+       bufferIndex = 0;
+       sampleBuffer = buffer;
+       numberOfSamples = length / 2;
+       bufferDone = false;
+
+       SetCallbackTime(DSPSampleCallback, 1000000.0 / (double)DAC_AUDIO_RATE, EVENT_JERRY);
+
+       // These timings are tied to NTSC, need to fix that in event.cpp/h!
+       do
+       {
+               double timeToNextEvent = GetTimeToNextEvent(EVENT_JERRY);
+
+               if (vjs.DSPEnabled)
+               {
+                       if (vjs.usePipelinedDSP)
+                               DSPExecP2(USEC_TO_RISC_CYCLES(timeToNextEvent));
+                       else
+                               DSPExec(USEC_TO_RISC_CYCLES(timeToNextEvent));
+               }
+
+               HandleNextEvent(EVENT_JERRY);
+       }
+       while (!bufferDone);
+
+       // We do this to prevent problems with trying to write past the end of the buffer...
+//     RemoveCallback(DSPSampleCallback);
+#endif
+}
+
+
+void DSPSampleCallback(void)
+{
+       ((uint16_t *)sampleBuffer)[bufferIndex + 0] = ltxd;
+       ((uint16_t *)sampleBuffer)[bufferIndex + 1] = rtxd;
+       bufferIndex += 2;
+
+       if (bufferIndex == numberOfSamples)
+       {
+               bufferDone = true;
+               return;
+       }
+
+       SetCallbackTime(DSPSampleCallback, 1000000.0 / (double)DAC_AUDIO_RATE, EVENT_JERRY);
+}
+#if 0
+       frameDone = false;
+
+       do
+       {
+               double timeToNextEvent = GetTimeToNextEvent();
+//WriteLog("JEN: Time to next event (%u) is %f usec (%u RISC cycles)...\n", nextEvent, timeToNextEvent, USEC_TO_RISC_CYCLES(timeToNextEvent));
+
+               m68k_execute(USEC_TO_M68K_CYCLES(timeToNextEvent));
+
+               if (vjs.GPUEnabled)
+                       GPUExec(USEC_TO_RISC_CYCLES(timeToNextEvent));
+
+#ifndef NEW_DAC_CODE
+               if (vjs.DSPEnabled)
+               {
+                       if (vjs.usePipelinedDSP)
+                               DSPExecP2(USEC_TO_RISC_CYCLES(timeToNextEvent));        // Pipelined DSP execution (3 stage)...
+                       else
+                               DSPExec(USEC_TO_RISC_CYCLES(timeToNextEvent));          // Ordinary non-pipelined DSP
+               }
+#endif
+
+               HandleNextEvent();
+       }
+       while (!frameDone);
+#endif
+
+
+//
+// SDL callback routine to fill audio buffer
+//
+// Note: The samples are packed in the buffer in 16 bit left/16 bit right pairs.
+//       Also, length is the length of the buffer in BYTES
 //
 void SDLSoundCallback(void * userdata, Uint8 * buffer, int length)
 {
@@ -219,6 +376,7 @@ if (numLeftSamplesReady == 0 || numRightSamplesReady == 0)
 //             WriteLog("DAC: Silence...!\n");
 }
 
+
 //
 // Calculate the frequency of SCLK * 32 using the divider
 //
@@ -231,10 +389,13 @@ int GetCalculatedFrequency(void)
        return systemClockFrequency / (32 * (2 * (SCLKFrequencyDivider + 1)));
 }
 
+
 static int oldFreq = 0;
 
 void DACSetNewFrequency(int freq)
 {
+#ifdef NEW_DAC_CODE
+#else
        if (freq == oldFreq)
                return;
 
@@ -267,8 +428,10 @@ void DACSetNewFrequency(int freq)
 
        if (SDLSoundInitialized)
                SDL_PauseAudio(false);                  // Start playback!
+#endif
 }
 
+
 //
 // LTXD/RTXD/SCLK/SMODE ($F1A148/4C/50/54)
 //
@@ -279,12 +442,17 @@ void DACWriteByte(uint32 offset, uint8 data, uint32 who/*= UNKNOWN*/)
                DACWriteWord(offset - 3, (uint16)data);
 }
 
+
 void DACWriteWord(uint32 offset, uint16 data, uint32 who/*= UNKNOWN*/)
 {
        if (offset == LTXD + 2)
        {
                if (!SDLSoundInitialized)
                        return;
+
+#ifdef NEW_DAC_CODE
+               ltxd = data;
+#else
                // Spin until buffer has been drained (for too fast processors!)...
 //Small problem--if Head == 0 and Tail == buffer end, then this will fail... !!! FIX !!!
 //[DONE]
@@ -321,6 +489,7 @@ WriteLog("Tail=%X, Head=%X", ltail, lhead);
                LeftFIFOTailPtr = (LeftFIFOTailPtr + 2) % BUFFER_SIZE;
                DACBuffer[LeftFIFOTailPtr] = data;
                SDL_UnlockAudio();
+#endif
        }
        else if (offset == RTXD + 2)
        {
@@ -381,6 +550,9 @@ LTail=60D8, LHead=60D8, BUFFER_SIZE-1=FFFF
 RTail=DB, RHead=60D9, BUFFER_SIZE-1=FFFF
 From while: Tail=60DA, Head=60D8
 */
+#ifdef NEW_DAC_CODE
+               rtxd = data;
+#else
 #warning Spinlock problem--!!! FIX !!!
 #warning Odd: The right FIFO is empty, but the left FIFO is full!
                // Spin until buffer has been drained (for too fast processors!)...
@@ -416,6 +588,7 @@ WriteLog("Tail=%X, Head=%X", rtail, rhead);
                else
                        WriteLog("DAC: Ran into FIFO's right tail pointer!\n");
 #endif*/
+#endif
        }
        else if (offset == SCLK + 2)                                    // Sample rate
        {
@@ -423,6 +596,8 @@ WriteLog("Tail=%X, Head=%X", rtail, rhead);
                if ((uint8)data != SCLKFrequencyDivider)
                {
                        SCLKFrequencyDivider = (uint8)data;
+#ifdef NEW_DAC_CODE
+#else
 //Of course a better way would be to query the hardware to find the upper limit...
                        if (data > 7)   // Anything less than 8 is too high!
                        {
@@ -452,6 +627,7 @@ WriteLog("Tail=%X, Head=%X", rtail, rhead);
                                if (SDLSoundInitialized)
                                        SDL_PauseAudio(false);                  // Start playback!
                        }
+#endif
                }
        }
        else if (offset == SMODE + 2)
@@ -465,6 +641,7 @@ WriteLog("Tail=%X, Head=%X", rtail, rhead);
        }
 }
 
+
 //
 // LRXD/RRXD/SSTAT ($F1A148/4C/50)
 //
@@ -474,6 +651,7 @@ uint8 DACReadByte(uint32 offset, uint32 who/*= UNKNOWN*/)
        return 0xFF;
 }
 
+
 //static uint16 fakeWord = 0;
 uint16 DACReadWord(uint32 offset, uint32 who/*= UNKNOWN*/)
 {
index 023855f014c3bcfc4619784d142ed5d64fed5717..ef30549a237436128fa1c4a15ea5c009d1249e98 100644 (file)
--- a/src/dac.h
+++ b/src/dac.h
@@ -5,6 +5,9 @@
 #ifndef __DAC_H__
 #define __DAC_H__
 
+//this is here, because we have to compensate in more than just dac.cpp...
+#define NEW_DAC_CODE                                                   // New code paths!
+
 //#include "types.h"
 #include "memory.h"
 
index 7db98aee391f516192d53100740fa0a4b3aaed46..d321d47b27339f3acb825685296f4dba8d17c7bd 100644 (file)
@@ -1280,6 +1280,11 @@ DSPHandleIRQsNP();
 //     GPUSetIRQLine(GPUIRQ_DSP, ASSERT_LINE);
 }
 
+bool DSPIsRunning(void)
+{
+       return (DSP_RUNNING ? true : false);
+}
+
 void DSPInit(void)
 {
 //     memory_malloc_secure((void **)&dsp_ram_8, 0x2000, "DSP work RAM");
index 44e8b70712f9d1288fe39bf6a401eca130bba570..67e52991bea17c643efe82a5049c7998201296d2 100644 (file)
--- a/src/dsp.h
+++ b/src/dsp.h
@@ -25,6 +25,7 @@ void DSPWriteByte(uint32 offset, uint8 data, uint32 who = UNKNOWN);
 void DSPWriteWord(uint32 offset, uint16 data, uint32 who = UNKNOWN);
 void DSPWriteLong(uint32 offset, uint32 data, uint32 who = UNKNOWN);
 void DSPReleaseTimeslice(void);
+bool DSPIsRunning(void);
 
 void DSPExecP(int32 cycles);
 void DSPExecP2(int32 cycles);
index b455cd60bf47498d123699fe3c677826f118ff0d..a923f3730725a2887b18794eb2b7332cfe0e9c74 100644 (file)
 #include "event.h"
 
 #include "log.h"
+#include "types.h"
 
-#define EVENT_LIST_SIZE       512
 
-/*
-// Current execution path:
-
-do
-{
-       HandleJoystick
-
-       // Execute one frame
-
-    for(int i=0; i<numLines; i++)
-    {
-               ExecuteM68K
-               ExecutePITs
-               ExecuteGPU
-               ExecuteDSP
-               // Render Scanline
-               CallObjectProcessor
-               MoveLineBufToBackBuf
-    }
-
-       RenderBackbuffer
-}
-while (true)
+//#define EVENT_LIST_SIZE       512
+#define EVENT_LIST_SIZE       32
 
-// What we need to do:
-
-Set up timers (frame [for native render--on vblank interval?], OP line, PITs)
-
-do
-{
-       double timeToNextEvent = GetTimeToNextEvent();
-
-       m68k_execute(USEC_TO_M68K_CYCLES(timeToNextEvent));
-       GPUExec(USEC_TO_RISC_CYCLES(timeToNextEvent));
-       DSPExec(USEC_TO_RISC_CYCLES(timeToNextEvent));
-
-       HandleNextEvent();
-}
-while (true)
-
-
-*/
 
 // Now, a bit of weirdness: It seems that the number of lines displayed on the screen
 // makes the effective refresh rate either 30 or 25 Hz!
@@ -80,136 +41,255 @@ while (true)
 
 struct Event
 {
-    bool valid;
-    double eventTime;
-    void (* timerCallback)(void);
+       bool valid;
+       int eventType;
+       double eventTime;
+       void (* timerCallback)(void);
 };
 
-Event eventList[EVENT_LIST_SIZE];
-uint32 nextEvent;
+
+static Event eventList[EVENT_LIST_SIZE];
+static Event eventListJERRY[EVENT_LIST_SIZE];
+static uint32_t nextEvent;
+static uint32_t nextEventJERRY;
+static uint32_t numberOfEvents;
+
 
 void InitializeEventList(void)
 {
-    for(uint32 i=0; i<EVENT_LIST_SIZE; i++)
-        eventList[i].valid = false;
+       for(uint32_t i=0; i<EVENT_LIST_SIZE; i++)
+       {
+               eventList[i].valid = false;
+               eventListJERRY[i].valid = false;
+       }
+
+       numberOfEvents = 0;
+       WriteLog("EVENT: Cleared event list.\n");
 }
 
-//We just slap the next event into the list, no checking, no nada...
-void SetCallbackTime(void (* callback)(void), double time)
+
+// Set callback time in Âµs. This is fairly arbitrary, but works well enough for our purposes.
+//We just slap the next event into the list in the first available slot, no checking, no nada...
+void SetCallbackTime(void (* callback)(void), double time, int type/*= EVENT_MAIN*/)
 {
-    for(uint32 i=0; i<EVENT_LIST_SIZE; i++)
-    {
-        if (!eventList[i].valid)
-        {
-//WriteLog("SCT: Found callback slot #%u...\n", i);
-            eventList[i].timerCallback = callback;
-            eventList[i].eventTime = time;
-            eventList[i].valid = true;
-
-            return;
-        }
-    }
-
-    WriteLog("SetCallbackTime() failed to find an empty slot in the list!\n");
+       if (type == EVENT_MAIN)
+       {
+               for(uint32_t i=0; i<EVENT_LIST_SIZE; i++)
+               {
+                       if (!eventList[i].valid)
+                       {
+//WriteLog("EVENT: Found callback slot #%u...\n", i);
+                               eventList[i].timerCallback = callback;
+                               eventList[i].eventTime = time;
+                               eventList[i].eventType = type;
+                               eventList[i].valid = true;
+                               numberOfEvents++;
+
+                               return;
+                       }
+               }
+
+               WriteLog("EVENT: SetCallbackTime() failed to find an empty slot in the main list (%u events)!\n", numberOfEvents);
+       }
+       else
+       {
+               for(uint32_t i=0; i<EVENT_LIST_SIZE; i++)
+               {
+                       if (!eventListJERRY[i].valid)
+                       {
+//WriteLog("EVENT: Found callback slot #%u...\n", i);
+                               eventListJERRY[i].timerCallback = callback;
+                               eventListJERRY[i].eventTime = time;
+                               eventListJERRY[i].eventType = type;
+                               eventListJERRY[i].valid = true;
+                               numberOfEvents++;
+
+                               return;
+                       }
+               }
+
+               WriteLog("EVENT: SetCallbackTime() failed to find an empty slot in the main list (%u events)!\n", numberOfEvents);
+       }
 }
 
+
 void RemoveCallback(void (* callback)(void))
 {
-    for(uint32 i=0; i<EVENT_LIST_SIZE; i++)
-    {
-        if (eventList[i].valid && eventList[i].timerCallback == callback)
-        {
-            eventList[i].valid = false;
-
-            return;
-        }
-    }
+       for(uint32_t i=0; i<EVENT_LIST_SIZE; i++)
+       {
+               if (eventList[i].valid && eventList[i].timerCallback == callback)
+               {
+                       eventList[i].valid = false;
+                       numberOfEvents--;
+
+                       return;
+               }
+               else if (eventListJERRY[i].valid && eventListJERRY[i].timerCallback == callback)
+               {
+                       eventListJERRY[i].valid = false;
+                       numberOfEvents--;
+
+                       return;
+               }
+       }
 }
 
+
 void AdjustCallbackTime(void (* callback)(void), double time)
 {
-    for(uint32 i=0; i<EVENT_LIST_SIZE; i++)
-    {
-        if (eventList[i].valid && eventList[i].timerCallback == callback)
-        {
-            eventList[i].eventTime = time;
-
-            return;
-        }
-    }
+       for(uint32_t i=0; i<EVENT_LIST_SIZE; i++)
+       {
+               if (eventList[i].valid && eventList[i].timerCallback == callback)
+               {
+                       eventList[i].eventTime = time;
+
+                       return;
+               }
+               else if (eventListJERRY[i].valid && eventListJERRY[i].timerCallback == callback)
+               {
+                       eventListJERRY[i].eventTime = time;
+
+                       return;
+               }
+       }
 }
 
-double GetTimeToNextEvent(void)
-{
-    double time = 0;
-    bool firstTime = true;
-
-    for(uint32 i=0; i<EVENT_LIST_SIZE; i++)
-    {
-        if (eventList[i].valid)
-        {
-            if (firstTime)
-                time = eventList[i].eventTime, nextEvent = i, firstTime = false;
-            else
-            {
-                if (eventList[i].eventTime < time)
-                    time = eventList[i].eventTime, nextEvent = i;
-            }
-        }
-    }
-
-    return time;
-}
 
-void HandleNextEvent(void)
+//
+// Since our list is unordered WRT time, we have to search it to find the next event
+// Returns time to next event & sets nextEvent to that event
+//
+double GetTimeToNextEvent(int type/*= EVENT_MAIN*/)
 {
-    double elapsedTime = eventList[nextEvent].eventTime;
-    void (* event)(void) = eventList[nextEvent].timerCallback;
-
-    for(uint32 i=0; i<EVENT_LIST_SIZE; i++)
-        if (eventList[i].valid)
-            eventList[i].eventTime -= elapsedTime;
+#if 0
+       double time = 0;
+       bool firstTime = true;
+
+       for(uint32 i=0; i<EVENT_LIST_SIZE; i++)
+       {
+               if (eventList[i].valid)
+               {
+                       if (firstTime)
+                               time = eventList[i].eventTime, nextEvent = i, firstTime = false;
+                       else
+                       {
+                               if (eventList[i].eventTime < time)
+                                       time = eventList[i].eventTime, nextEvent = i;
+                       }
+               }
+       }
+#else
+       if (type == EVENT_MAIN)
+       {
+               double time = eventList[0].eventTime;
+               nextEvent = 0;
+
+               for(uint32_t i=1; i<EVENT_LIST_SIZE; i++)
+               {
+                       if (eventList[i].valid && (eventList[i].eventTime < time))
+                       {
+                               time = eventList[i].eventTime;
+                               nextEvent = i;
+                       }
+               }
+
+               return time;
+       }
+       else
+       {
+               double time = eventListJERRY[0].eventTime;
+               nextEventJERRY = 0;
+
+               for(uint32_t i=1; i<EVENT_LIST_SIZE; i++)
+               {
+                       if (eventListJERRY[i].valid && (eventListJERRY[i].eventTime < time))
+                       {
+                               time = eventListJERRY[i].eventTime;
+                               nextEventJERRY = i;
+                       }
+               }
+
+               return time;
+       }
+#endif
+}
 
-    eventList[nextEvent].valid = false;      // Remove event from list...
 
-    (*event)();
+void HandleNextEvent(int type/*= EVENT_MAIN*/)
+{
+       if (type == EVENT_MAIN)
+       {
+               double elapsedTime = eventList[nextEvent].eventTime;
+               void (* event)(void) = eventList[nextEvent].timerCallback;
+
+               for(uint32_t i=0; i<EVENT_LIST_SIZE; i++)
+               {
+       //We can skip the check & just subtract from everything, since the check is probably
+       //just as heavy as the code after and we won't use the elapsed time from an invalid event anyway.
+       //              if (eventList[i].valid)
+                               eventList[i].eventTime -= elapsedTime;
+               }
+
+               eventList[nextEvent].valid = false;                     // Remove event from list...
+               numberOfEvents--;
+
+               (*event)();
+       }
+       else
+       {
+               double elapsedTime = eventListJERRY[nextEventJERRY].eventTime;
+               void (* event)(void) = eventListJERRY[nextEventJERRY].timerCallback;
+
+               for(uint32_t i=0; i<EVENT_LIST_SIZE; i++)
+               {
+       //We can skip the check & just subtract from everything, since the check is probably
+       //just as heavy as the code after and we won't use the elapsed time from an invalid event anyway.
+       //              if (eventList[i].valid)
+                               eventListJERRY[i].eventTime -= elapsedTime;
+               }
+
+               eventListJERRY[nextEventJERRY].valid = false;   // Remove event from list...
+               numberOfEvents--;
+
+               (*event)();
+       }
 }
 
 
 /*
 void OPCallback(void)
 {
-    DoFunkyOPStuffHere();
+       DoFunkyOPStuffHere();
 
-    SetCallbackTime(OPCallback, HORIZ_PERIOD_IN_USEC);
+       SetCallbackTime(OPCallback, HORIZ_PERIOD_IN_USEC);
 }
 
 void VICallback(void)
 {
-    double oneFrameInUsec = 16666.66666666;
-    SetCallbackTime(VICallback, oneFrameInUsec / numberOfLines);
+       double oneFrameInUsec = 16666.66666666;
+       SetCallbackTime(VICallback, oneFrameInUsec / numberOfLines);
 }
 
 void JaguarInit(void)
 {
-    double oneFrameInUsec = 16666.66666666;
-    SetCallbackTime(VICallback, oneFrameInUsec / numberOfLines);
-    SetCallbackTime(OPCallback, );
+       double oneFrameInUsec = 16666.66666666;
+       SetCallbackTime(VICallback, oneFrameInUsec / numberOfLines);
+       SetCallbackTime(OPCallback, );
 }
 
 void JaguarExec(void)
 {
-    while (true)
-    {
-        double timeToNextEvent = GetTimeToNextEvent();
+       while (true)
+       {
+               double timeToNextEvent = GetTimeToNextEvent();
 
-        m68k_execute(USEC_TO_M68K_CYCLES(timeToNextEvent));
-        GPUExec(USEC_TO_RISC_CYCLES(timeToNextEvent));
-        DSPExec(USEC_TO_RISC_CYCLES(timeToNextEvent));
+               m68k_execute(USEC_TO_M68K_CYCLES(timeToNextEvent));
+               GPUExec(USEC_TO_RISC_CYCLES(timeToNextEvent));
+               DSPExec(USEC_TO_RISC_CYCLES(timeToNextEvent));
 
-        if (!HandleNextEvent())
-            break;
-    }
+               if (!HandleNextEvent())
+                       break;
+       }
 }
 
 // NOTES: The timers count RISC cycles, and when the dividers count down to zero they can interrupt either the DSP and/or CPU.
@@ -221,25 +301,25 @@ void JaguarExec(void)
 
 void TOMResetPIT()
 {
-    // Need to remove previous timer from the queue, if it exists...
-    RemoveCallback(TOMPITCallback);
-
-    if (TOMPITPrescaler)
-    {
-        double usecs = (TOMPITPrescaler + 1) * (TOMPITDivider + 1) * RISC_CYCLE_IN_USEC;
-        SetCallbackTime(TOMPITCallback, usecs);
-    }
+       // Need to remove previous timer from the queue, if it exists...
+       RemoveCallback(TOMPITCallback);
+
+       if (TOMPITPrescaler)
+       {
+               double usecs = (TOMPITPrescaler + 1) * (TOMPITDivider + 1) * RISC_CYCLE_IN_USEC;
+               SetCallbackTime(TOMPITCallback, usecs);
+       }
 }
 
 void TOMPITCallback(void)
 {
-    INT1_RREG |= 0x08;                         // Set TOM PIT interrupt pending
-    GPUSetIRQLine(GPUIRQ_TIMER, ASSERT_LINE);  // It does the 'IRQ enabled' checking
+       INT1_RREG |= 0x08;                         // Set TOM PIT interrupt pending
+       GPUSetIRQLine(GPUIRQ_TIMER, ASSERT_LINE);  // It does the 'IRQ enabled' checking
 
-    if (INT1_WREG & 0x08)
-        m68k_set_irq(2);                       // Generate 68K NMI
+       if (INT1_WREG & 0x08)
+               m68k_set_irq(2);                       // Generate 68K NMI
 
-    TOMResetPIT();
+       TOMResetPIT();
 }
 
 // Small problem with this approach: If a timer interrupt is already pending,
@@ -247,16 +327,16 @@ void TOMPITCallback(void)
 
 TOMWriteWord(uint32 address, uint16 data)
 {
-    if (address == PIT0)
-    {
-        TOMPITPrescaler = data;
-        TOMResetPIT();
-    }
-    else if (address == PIT1)
-    {
-        TOMPITDivider = data;
-        TOMResetPIT();
-    }
+       if (address == PIT0)
+       {
+               TOMPITPrescaler = data;
+               TOMResetPIT();
+       }
+       else if (address == PIT1)
+       {
+               TOMPITDivider = data;
+               TOMResetPIT();
+       }
 }
 
 */
index 5565bec85af9a324134c2a6d2a7f6b6c2997da52..ae6ab3821a4a454b64a02fed31af9c15b9d026dd 100644 (file)
@@ -7,10 +7,14 @@
 #ifndef __EVENT_H__
 #define __EVENT_H__
 
-#include "types.h"
+enum { EVENT_MAIN, EVENT_JERRY };
 
+//NTSC Timings...
 #define RISC_CYCLE_IN_USEC        0.03760684198
 #define M68K_CYCLE_IN_USEC        (RISC_CYCLE_IN_USEC * 2)
+//PAL Timings
+#define RISC_CYCLE_PAL_IN_USEC         0.03760260812
+#define M68K_CYCLE_PAL_IN_USEC         (RISC_CYCLE_PAL_IN_USEC * 2)
 
 #define HORIZ_PERIOD_IN_USEC_NTSC 63.555555555
 #define HORIZ_PERIOD_IN_USEC_PAL  64.0
 #define USEC_TO_M68K_CYCLES(u) (uint32)(((u) / M68K_CYCLE_IN_USEC) + 0.5)
 
 void InitializeEventList(void);
-void SetCallbackTime(void (* callback)(void), double time);
+void SetCallbackTime(void (* callback)(void), double time, int type = EVENT_MAIN);
 void RemoveCallback(void (* callback)(void));
 void AdjustCallbackTime(void (* callback)(void), double time);
-double GetTimeToNextEvent(void);
-void HandleNextEvent(void);
+double GetTimeToNextEvent(int type = EVENT_MAIN);
+void HandleNextEvent(int type = EVENT_MAIN);
 
 #endif // __EVENT_H__
index b8a7de0f610526534ee267d54edfc146133238ac..7a026c7b31eee3b5eb23a8750244f7e2c30ad0bf 100644 (file)
@@ -691,6 +691,8 @@ void MainWin::ResizeMainWindow(void)
        }
 }
 
+#warning "!!! Need to check the window geometry to see if the positions are legal !!!"
+// i.e., someone could drag it to another screen, close it, then disconnect that screen
 void MainWin::ReadSettings(void)
 {
        QSettings settings("Underground Software", "Virtual Jaguar");
@@ -731,6 +733,7 @@ WriteLog("   EEPROMPath = \"%s\"\n", vjs.EEPROMPath);
 WriteLog("      ROMPath = \"%s\"\n", vjs.ROMPath);
 WriteLog("AlpineROMPath = \"%s\"\n", vjs.alpineROMPath);
 WriteLog("   absROMPath = \"%s\"\n", vjs.absROMPath);
+WriteLog("Pipelined DSP = %s\n", (vjs.usePipelinedDSP ? "ON" : "off"));
 
        // Keybindings in order of U, D, L, R, C, B, A, Op, Pa, 0-9, #, *
        vjs.p1KeyBindings[BUTTON_U] = settings.value("p1k_up", Qt::Key_S).toInt();
index bb940718ba9122a4fbbc2358f0cf8f4f6c4654a0..a943768cfd1cad35a19952e8248906e44d5bf5a3 100644 (file)
@@ -852,7 +852,7 @@ void ShowM68KContext(void)
 }
 
 //
-// Musashi 68000 read/write/IRQ functions
+// Custom UAE 68000 read/write/IRQ functions
 //
 
 #if 0
@@ -1750,6 +1750,8 @@ void HalflineCallback(void);
 void RenderCallback(void);
 void JaguarReset(void)
 {
+       // New timer base code stuffola...
+       InitializeEventList();
 //Need to change this so it uses the single RAM space and load the BIOS
 //into it somewhere...
 //Also, have to change this here and in JaguarReadXX() currently
@@ -1770,8 +1772,6 @@ void JaguarReset(void)
        WriteLog("Jaguar: 68K reset. PC=%06X SP=%08X\n", m68k_get_reg(NULL, M68K_REG_PC), m68k_get_reg(NULL, M68K_REG_A7));
 
        lowerField = false;                                                             // Reset the lower field flag
-       // New timer base code stuffola...
-       InitializeEventList();
 //     SetCallbackTime(ScanlineCallback, 63.5555);
 //     SetCallbackTime(ScanlineCallback, 31.77775);
        SetCallbackTime(HalflineCallback, (vjs.hardwareTypeNTSC ? 31.777777777 : 32.0));
@@ -1911,89 +1911,6 @@ void JaguarDone(void)
 //     JaguarDasm(0x800800, 0x1000);
 }
 
-//
-// Main Jaguar execution loop (1 frame)
-//
-void JaguarExecute(uint32 * backbuffer, bool render)
-{
-       uint16 vp = TOMReadWord(0xF0003E, JAGUAR) + 1;
-       uint16 vi = TOMReadWord(0xF0004E, JAGUAR);
-//Using WO registers is OK, since we're the ones controlling access--there's nothing wrong here! ;-)
-//Though we shouldn't be able to do it using TOMReadWord... !!! FIX !!!
-
-//     uint16 vdb = TOMReadWord(0xF00046, JAGUAR);
-//Note: This is the *definite* end of the display, though VDE *might* be less than this...
-//     uint16 vbb = TOMReadWord(0xF00040, JAGUAR);
-//It seems that they mean it when they say that VDE is the end of object processing.
-//However, we need to be able to tell the OP (or TOM) that we've reached the end of the
-//buffer and not to write any more pixels... !!! FIX !!!
-//     uint16 vde = TOMReadWord(0xF00048, JAGUAR);
-
-       uint16 refreshRate = (vjs.hardwareTypeNTSC ? 60 : 50);
-       uint32 m68kClockRate = (vjs.hardwareTypeNTSC ? M68K_CLOCK_RATE_NTSC : M68K_CLOCK_RATE_PAL);
-//Not sure the above is correct, since the number of lines and timings given in the JTRM
-//seem to indicate the refresh rate is *half* the above...
-//     uint16 refreshRate = (vjs.hardwareTypeNTSC ? 30 : 25);
-       // Should these be hardwired or read from VP? Yes, from VP!
-       // Err, actually, they should be hardwired, and hardwired to a set # of
-       // lines as well...
-       uint32 M68KCyclesPerScanline = m68kClockRate / (vp * refreshRate);
-       uint32 RISCCyclesPerScanline = m68kClockRate / (vp * refreshRate);
-
-/*extern int effect_start;
-if (effect_start)
-       WriteLog("JagExe: VP=%u, VI=%u, CPU CPS=%u, GPU CPS=%u\n", vp, vi, M68KCyclesPerScanline, RISCCyclesPerScanline);//*/
-
-//extern int start_logging;
-       for(uint16 i=0; i<vp; i++)
-       {
-               // Increment the horizontal count (why? RNG? Besides which, this is *NOT* cycle accurate!)
-               TOMWriteWord(0xF00004, (TOMReadWord(0xF00004, JAGUAR) + 1) & 0x7FF, JAGUAR);
-               TOMWriteWord(0xF00006, i, JAGUAR);                      // Write the VC
-
-//Not sure if this is correct...
-//Seems to be, kinda. According to the JTRM, this should only fire on odd lines in non-interlace mode...
-//Which means that it normally wouldn't go when it's zero.
-               if (i == vi && i > 0 && TOMIRQEnabled(IRQ_VIDEO))       // Time for Vertical Interrupt?
-               {
-                       // We don't have to worry about autovectors & whatnot because the Jaguar
-                       // tells you through its HW registers who sent the interrupt...
-                       TOMSetPendingVideoInt();
-                       m68k_set_irq(2);
-               }
-
-//if (start_logging)
-//     WriteLog("About to execute M68K (%u)...\n", i);
-               m68k_execute(M68KCyclesPerScanline);
-//if (start_logging)
-//     WriteLog("About to execute TOM's PIT (%u)...\n", i);
-               TOMExecPIT(RISCCyclesPerScanline);
-//if (start_logging)
-//     WriteLog("About to execute JERRY's PIT (%u)...\n", i);
-               JERRYExecPIT(RISCCyclesPerScanline);
-//if (start_logging)
-//     WriteLog("About to execute JERRY's SSI (%u)...\n", i);
-               JERRYI2SExec(RISCCyclesPerScanline);
-               BUTCHExec(RISCCyclesPerScanline);
-//if (start_logging)
-//     WriteLog("About to execute GPU (%u)...\n", i);
-               if (vjs.GPUEnabled)
-                       GPUExec(RISCCyclesPerScanline);
-
-               if (vjs.DSPEnabled)
-               {
-                       if (vjs.usePipelinedDSP)
-                               DSPExecP2(RISCCyclesPerScanline);       // Pipelined DSP execution (3 stage)...
-                       else
-                               DSPExec(RISCCyclesPerScanline);         // Ordinary non-pipelined DSP
-//                     DSPExecComp(RISCCyclesPerScanline);             // Comparison core
-               }
-
-//if (start_logging)
-//     WriteLog("About to execute OP (%u)...\n", i);
-               TOMExecHalfline(i, render);
-       }
-}
 
 // Temp debugging stuff
 
@@ -2008,11 +1925,13 @@ void DumpMainMemory(void)
        fclose(fp);
 }
 
+
 uint8 * GetRamPtr(void)
 {
        return jaguarMainRAM;
 }
 
+
 //
 // New Jaguar execution stack
 // This executes 1 frame's worth of code.
@@ -2032,6 +1951,7 @@ void JaguarExecuteNew(void)
                if (vjs.GPUEnabled)
                        GPUExec(USEC_TO_RISC_CYCLES(timeToNextEvent));
 
+#ifndef NEW_DAC_CODE
                if (vjs.DSPEnabled)
                {
                        if (vjs.usePipelinedDSP)
@@ -2039,12 +1959,14 @@ void JaguarExecuteNew(void)
                        else
                                DSPExec(USEC_TO_RISC_CYCLES(timeToNextEvent));          // Ordinary non-pipelined DSP
                }
+#endif
 
                HandleNextEvent();
        }
        while (!frameDone);
 }
 
+
 #define USE_CORRECT_PAL_TIMINGS
 // A lot of confusion comes from here...
 // The thing to keep in mind is that the VC is advanced every HALF line, regardless
@@ -2129,6 +2051,7 @@ void HalflineCallback(void)
 #endif
 }
 
+
 // This isn't currently used, but maybe it should be...
 /*
 Nah, the scanline based code is good enough, and runs in 1 frame. The GUI
index d0d44af429fc0bfade5f97c58157ed0e227ab69c..0b44b8f731fd036a3bb2b7765cf46eb09524c60f 100644 (file)
 #include "wavetable.h"
 
 //Note that 44100 Hz requires samples every 22.675737 usec.
-#define NEW_TIMER_SYSTEM
 //#define JERRY_DEBUG
 
 /*static*/ uint8 jerry_ram_8[0x10000];
@@ -193,6 +192,7 @@ uint32 jerryIntPending;
 
 static uint16 jerryInterruptMask = 0;
 static uint16 jerryPendingInterrupt = 0;
+
 // Private function prototypes
 
 void JERRYResetPIT1(void);
@@ -203,100 +203,6 @@ void JERRYPIT1Callback(void);
 void JERRYPIT2Callback(void);
 void JERRYI2SCallback(void);
 
-//This approach is probably wrong, since the timer is continuously counting down, though
-//it might only be a problem if the # of interrupts generated is greater than 1--the M68K's
-//timeslice should be running during that phase... (The DSP needs to be aware of this!)
-
-//This is only used by the old system, so once the new timer system is working this
-//should be safe to nuke.
-void JERRYI2SExec(uint32 cycles)
-{
-#ifndef NEW_TIMER_SYSTEM
-#warning "externed var in source--should be in header file. !!! FIX !!!"
-       extern uint16 serialMode;                                               // From DAC.CPP
-       if (serialMode & 0x01)                                                  // INTERNAL flag (JERRY is master)
-       {
-
-       // Why is it called this? Instead of SCLK? Shouldn't this be read from DAC.CPP???
-//Yes, it should. !!! FIX !!!
-               JERRYI2SInterruptDivide &= 0xFF;
-
-               if (JERRYI2SInterruptTimer == -1)
-               {
-               // We don't have to divide the RISC clock rate by this--the reason is a bit
-               // convoluted. Will put explanation here later...
-// What's needed here is to find the ratio of the frequency to the number of clock cycles
-// in one second. For example, if the sample rate is 44100, we divide the clock rate by
-// this: 26590906 / 44100 = 602 cycles.
-// Which means, every 602 cycles that go by we have to generate an interrupt.
-                       jerryI2SCycles = 32 * (2 * (JERRYI2SInterruptDivide + 1));
-               }
-
-               JERYI2SInterruptTimer -= cycles;
-               if (JERRYI2SInterruptTimer <= 0)
-               {
-//This is probably wrong as well (i.e., need to check enable lines)... !!! FIX !!!
-                       DSPSetIRQLine(DSPIRQ_SSI, ASSERT_LINE);
-                       JERRYI2SInterruptTimer += jerryI2SCycles;
-#ifdef JERRY_DEBUG
-                       if (JERRYI2SInterruptTimer < 0)
-                               WriteLog("JERRY: Missed generating an interrupt (missed %u)!\n", (-JERRYI2SInterruptTimer / jerryI2SCycles) + 1);
-#endif
-               }
-       }
-       else                                                                                    // JERRY is slave to external word clock
-       {
-               // This is just a temporary kludge to see if the CD bus mastering works
-               // I.e., this is totally faked...!
-// The whole interrupt system is pretty much borked and is need of an overhaul.
-// What we need is a way of handling these interrupts when they happen instead of
-// scanline boundaries the way it is now.
-               JERRYI2SInterruptTimer -= cycles;
-               if (JERRYI2SInterruptTimer <= 0)
-               {
-//This is probably wrong as well (i.e., need to check enable lines)... !!! FIX !!! [DONE]
-                       if (ButchIsReadyToSend())//Not sure this is right spot to check...
-                       {
-//     return GetWordFromButchSSI(offset, who);
-                               SetSSIWordsXmittedFromButch();
-                               DSPSetIRQLine(DSPIRQ_SSI, ASSERT_LINE);
-                       }
-                       JERRYI2SInterruptTimer += 602;
-               }
-       }
-#else
-       RemoveCallback(JERRYI2SCallback);
-       JERRYI2SCallback();
-#endif
-}
-
-//NOTE: This is only used by the old execution core. Safe to nuke once it's stable.
-void JERRYExecPIT(uint32 cycles)
-{
-//This is wrong too: Counters are *always* spinning! !!! FIX !!! [DONE]
-//     if (jerry_timer_1_counter)
-               jerry_timer_1_counter -= cycles;
-
-       if (jerry_timer_1_counter <= 0)
-       {
-//Also, it can generate a CPU interrupt as well... !!! FIX !!! or does it? Maybe it goes Timer->GPU->CPU?
-               DSPSetIRQLine(DSPIRQ_TIMER0, ASSERT_LINE);      // This does the 'IRQ enabled' checking...
-//             JERRYResetPIT1();
-               jerry_timer_1_counter += (JERRYPIT1Prescaler + 1) * (JERRYPIT1Divider + 1);
-       }
-
-//This is wrong too: Counters are *always* spinning! !!! FIX !!! [DONE]
-//     if (jerry_timer_2_counter)
-               jerry_timer_2_counter -= cycles;
-
-       if (jerry_timer_2_counter <= 0)
-       {
-//Also, it can generate a CPU interrupt as well... !!! FIX !!! or does it? Maybe it goes Timer->GPU->CPU?
-               DSPSetIRQLine(DSPIRQ_TIMER1, ASSERT_LINE);      // This does the 'IRQ enabled' checking...
-//             JERRYResetPIT2();
-               jerry_timer_2_counter += (JERRYPIT2Prescaler + 1) * (JERRYPIT2Divider + 1);
-       }
-}
 
 void JERRYResetI2S(void)
 {
@@ -306,54 +212,31 @@ void JERRYResetI2S(void)
        JERRYI2SInterruptTimer = -1;
 }
 
+
 void JERRYResetPIT1(void)
 {
-#ifndef NEW_TIMER_SYSTEM
-/*     if (!JERRYPIT1Prescaler || !JERRYPIT1Divider)
-               jerry_timer_1_counter = 0;
-       else//*/
-//Small problem with this approach: Overflow if both are = $FFFF. !!! FIX !!!
-               jerry_timer_1_counter = (JERRYPIT1Prescaler + 1) * (JERRYPIT1Divider + 1);
-
-//     if (jerry_timer_1_counter)
-//             WriteLog("jerry: reseting timer 1 to 0x%.8x (%i)\n",jerry_timer_1_counter,jerry_timer_1_counter);
-
-#else
        RemoveCallback(JERRYPIT1Callback);
 
        if (JERRYPIT1Prescaler | JERRYPIT1Divider)
        {
                double usecs = (float)(JERRYPIT1Prescaler + 1) * (float)(JERRYPIT1Divider + 1) * RISC_CYCLE_IN_USEC;
-               SetCallbackTime(JERRYPIT1Callback, usecs);
+               SetCallbackTime(JERRYPIT1Callback, usecs, EVENT_JERRY);
        }
-#endif
 }
 
+
 void JERRYResetPIT2(void)
 {
-#ifndef NEW_TIMER_SYSTEM
-/*     if (!JERRYPIT2Prescaler || !JERRYPIT2Divider)
-       {
-               jerry_timer_2_counter = 0;
-               return;
-       }
-       else//*/
-               jerry_timer_2_counter = (JERRYPIT2Prescaler + 1) * (JERRYPIT2Divider + 1);
-
-//     if (jerry_timer_2_counter)
-//             WriteLog("jerry: reseting timer 2 to 0x%.8x (%i)\n",jerry_timer_2_counter,jerry_timer_2_counter);
-
-#else
        RemoveCallback(JERRYPIT2Callback);
 
        if (JERRYPIT1Prescaler | JERRYPIT1Divider)
        {
                double usecs = (float)(JERRYPIT2Prescaler + 1) * (float)(JERRYPIT2Divider + 1) * RISC_CYCLE_IN_USEC;
-               SetCallbackTime(JERRYPIT2Callback, usecs);
+               SetCallbackTime(JERRYPIT2Callback, usecs, EVENT_JERRY);
        }
-#endif
 }
 
+
 // This is the cause of the regressions in Cybermorph and Missile Command 3D...
 // Solution: Probably have to check the DSP enable bit before sending these thru.
 //#define JERRY_NO_IRQS
@@ -377,6 +260,7 @@ void JERRYPIT1Callback(void)
        JERRYResetPIT1();
 }
 
+
 void JERRYPIT2Callback(void)
 {
 #ifndef JERRY_NO_IRQS
@@ -395,6 +279,7 @@ void JERRYPIT2Callback(void)
        JERRYResetPIT2();
 }
 
+
 void JERRYI2SCallback(void)
 {
        // Why is it called this? Instead of SCLK? Shouldn't this be read from DAC.CPP???
@@ -417,7 +302,7 @@ void JERRYI2SCallback(void)
        {
                DSPSetIRQLine(DSPIRQ_SSI, ASSERT_LINE);         // This does the 'IRQ enabled' checking...
                double usecs = (float)jerryI2SCycles * RISC_CYCLE_IN_USEC;
-               SetCallbackTime(JERRYI2SCallback, usecs);
+               SetCallbackTime(JERRYI2SCallback, usecs, EVENT_JERRY);
        }
        else                                                                                    // JERRY is slave to external word clock
        {
@@ -449,7 +334,7 @@ void JERRYI2SCallback(void)
                        DSPSetIRQLine(DSPIRQ_SSI, ASSERT_LINE);
                }
 
-               SetCallbackTime(JERRYI2SCallback, 22.675737);
+               SetCallbackTime(JERRYI2SCallback, 22.675737, EVENT_JERRY);
        }
 }
 
@@ -457,7 +342,6 @@ void JERRYI2SCallback(void)
 void JERRYInit(void)
 {
        JoystickInit();
-       DACInit();
        memcpy(&jerry_ram_8[0xD000], waveTableROM, 0x1000);
 
        JERRYPIT1Prescaler = 0xFFFF;
@@ -466,14 +350,16 @@ void JERRYInit(void)
        JERRYPIT2Divider = 0xFFFF;
        jerryInterruptMask = 0x0000;
        jerryPendingInterrupt = 0x0000;
+
+       DACInit();
 }
 
+
 void JERRYReset(void)
 {
        JoystickReset();
        EepromReset();
        JERRYResetI2S();
-       DACReset();
 
        memset(jerry_ram_8, 0x00, 0xD000);              // Don't clear out the Wavetable ROM...!
        JERRYPIT1Prescaler = 0xFFFF;
@@ -484,8 +370,11 @@ void JERRYReset(void)
        jerry_timer_2_counter = 0;
        jerryInterruptMask = 0x0000;
        jerryPendingInterrupt = 0x0000;
+
+       DACReset();
 }
 
+
 void JERRYDone(void)
 {
        WriteLog("JERRY: M68K Interrupt control ($F10020) = %04X\n", GET16(jerry_ram_8, 0x20));
@@ -494,6 +383,7 @@ void JERRYDone(void)
        EepromDone();
 }
 
+
 bool JERRYIRQEnabled(int irq)
 {
        // Read the word @ $F10020
@@ -501,6 +391,7 @@ bool JERRYIRQEnabled(int irq)
        return jerryInterruptMask & irq;
 }
 
+
 void JERRYSetPendingIRQ(int irq)
 {
        // This is the shadow of INT (it's a split RO/WO register)
@@ -508,6 +399,7 @@ void JERRYSetPendingIRQ(int irq)
        jerryPendingInterrupt |= irq;
 }
 
+
 //
 // JERRY byte access (read)
 //
@@ -536,43 +428,7 @@ uint8 JERRYReadByte(uint32 offset, uint32 who/*=UNKNOWN*/)
 //under the new system... !!! FIX !!!
        else if ((offset >= 0xF10036) && (offset <= 0xF1003D))
        {
-#ifndef NEW_TIMER_SYSTEM
-//             jerry_timer_1_counter = (JERRYPIT1Prescaler + 1) * (JERRYPIT1Divider + 1);
-               uint32 counter1Hi = (jerry_timer_1_counter / (JERRYPIT1Divider + 1)) - 1;
-               uint32 counter1Lo = (jerry_timer_1_counter % (JERRYPIT1Divider + 1)) - 1;
-               uint32 counter2Hi = (jerry_timer_2_counter / (JERRYPIT2Divider + 1)) - 1;
-               uint32 counter2Lo = (jerry_timer_2_counter % (JERRYPIT2Divider + 1)) - 1;
-
-               switch(offset & 0x0F)
-               {
-               case 6:
-//                     return JERRYPIT1Prescaler >> 8;
-                       return counter1Hi >> 8;
-               case 7:
-//                     return JERRYPIT1Prescaler & 0xFF;
-                       return counter1Hi & 0xFF;
-               case 8:
-//                     return JERRYPIT1Divider >> 8;
-                       return counter1Lo >> 8;
-               case 9:
-//                     return JERRYPIT1Divider & 0xFF;
-                       return counter1Lo & 0xFF;
-               case 10:
-//                     return JERRYPIT2Prescaler >> 8;
-                       return counter2Hi >> 8;
-               case 11:
-//                     return JERRYPIT2Prescaler & 0xFF;
-                       return counter2Hi & 0xFF;
-               case 12:
-//                     return JERRYPIT2Divider >> 8;
-                       return counter2Lo >> 8;
-               case 13:
-//                     return JERRYPIT2Divider & 0xFF;
-                       return counter2Lo & 0xFF;
-               }
-#else
 WriteLog("JERRY: Unhandled timer read (BYTE) at %08X...\n", offset);
-#endif
        }
 //     else if (offset >= 0xF10010 && offset <= 0xF10015)
 //             return clock_byte_read(offset);
@@ -586,6 +442,7 @@ WriteLog("JERRY: Unhandled timer read (BYTE) at %08X...\n", offset);
        return jerry_ram_8[offset & 0xFFFF];
 }
 
+
 //
 // JERRY word access (read)
 //
@@ -612,32 +469,7 @@ uint16 JERRYReadWord(uint32 offset, uint32 who/*=UNKNOWN*/)
 //in the jerry_timer_n_counter variables... !!! FIX !!! [DONE]
        else if ((offset >= 0xF10036) && (offset <= 0xF1003D))
        {
-#ifndef NEW_TIMER_SYSTEM
-//             jerry_timer_1_counter = (JERRYPIT1Prescaler + 1) * (JERRYPIT1Divider + 1);
-               uint32 counter1Hi = (jerry_timer_1_counter / (JERRYPIT1Divider + 1)) - 1;
-               uint32 counter1Lo = (jerry_timer_1_counter % (JERRYPIT1Divider + 1)) - 1;
-               uint32 counter2Hi = (jerry_timer_2_counter / (JERRYPIT2Divider + 1)) - 1;
-               uint32 counter2Lo = (jerry_timer_2_counter % (JERRYPIT2Divider + 1)) - 1;
-
-               switch(offset & 0x0F)
-               {
-               case 6:
-//                     return JERRYPIT1Prescaler;
-                       return counter1Hi;
-               case 8:
-//                     return JERRYPIT1Divider;
-                       return counter1Lo;
-               case 10:
-//                     return JERRYPIT2Prescaler;
-                       return counter2Hi;
-               case 12:
-//                     return JERRYPIT2Divider;
-                       return counter2Lo;
-               }
-               // Unaligned word reads???
-#else
 WriteLog("JERRY: Unhandled timer read (WORD) at %08X...\n", offset);
-#endif
        }
 //     else if ((offset >= 0xF10010) && (offset <= 0xF10015))
 //             return clock_word_read(offset);
@@ -660,6 +492,7 @@ WriteLog("JERRY: Unhandled timer read (WORD) at %08X...\n", offset);
        return ((uint16)jerry_ram_8[offset+0] << 8) | jerry_ram_8[offset+1];
 }
 
+
 //
 // JERRY byte access (write)
 //
@@ -689,12 +522,8 @@ void JERRYWriteByte(uint32 offset, uint8 data, uint32 who/*=UNKNOWN*/)
                        JERRYI2SInterruptDivide = (JERRYI2SInterruptDivide & 0xFF00) | (uint32)data;
 
                JERRYI2SInterruptTimer = -1;
-#ifndef NEW_TIMER_SYSTEM
-               jerry_i2s_exec(0);
-#else
                RemoveCallback(JERRYI2SCallback);
                JERRYI2SCallback();
-#endif
 //             return;
        }
        // LTXD/RTXD/SCLK/SMODE $F1A148/4C/50/54 (really 16-bit registers...)
@@ -705,44 +534,7 @@ void JERRYWriteByte(uint32 offset, uint8 data, uint32 who/*=UNKNOWN*/)
        }
        else if (offset >= 0xF10000 && offset <= 0xF10007)
        {
-#ifndef NEW_TIMER_SYSTEM
-               switch (offset & 0x07)
-               {
-               case 0:
-                       JERRYPIT1Prescaler = (JERRYPIT1Prescaler & 0x00FF) | (data << 8);
-                       JERRYResetPIT1();
-                       break;
-               case 1:
-                       JERRYPIT1Prescaler = (JERRYPIT1Prescaler & 0xFF00) | data;
-                       JERRYResetPIT1();
-                       break;
-               case 2:
-                       JERRYPIT1Divider = (JERRYPIT1Divider & 0x00FF) | (data << 8);
-                       JERRYResetPIT1();
-                       break;
-               case 3:
-                       JERRYPIT1Divider = (JERRYPIT1Divider & 0xFF00) | data;
-                       JERRYResetPIT1();
-                       break;
-               case 4:
-                       JERRYPIT2Prescaler = (JERRYPIT2Prescaler & 0x00FF) | (data << 8);
-                       JERRYResetPIT2();
-                       break;
-               case 5:
-                       JERRYPIT2Prescaler = (JERRYPIT2Prescaler & 0xFF00) | data;
-                       JERRYResetPIT2();
-                       break;
-               case 6:
-                       JERRYPIT2Divider = (JERRYPIT2Divider & 0x00FF) | (data << 8);
-                       JERRYResetPIT2();
-                       break;
-               case 7:
-                       JERRYPIT2Divider = (JERRYPIT2Divider & 0xFF00) | data;
-                       JERRYResetPIT2();
-               }
-#else
 WriteLog("JERRY: Unhandled timer write (BYTE) at %08X...\n", offset);
-#endif
                return;
        }
 /*     else if ((offset >= 0xF10010) && (offset <= 0xF10015))
@@ -787,6 +579,7 @@ WriteLog("JERRY: Unhandled timer write (BYTE) at %08X...\n", offset);
        jerry_ram_8[offset & 0xFFFF] = data;
 }
 
+
 //
 // JERRY word access (write)
 //
@@ -838,12 +631,8 @@ else if (offset == 0xF10020)
 //This should *only* be enabled when SMODE has its INTERNAL bit set! !!! FIX !!!
                JERRYI2SInterruptDivide = (uint8)data;
                JERRYI2SInterruptTimer = -1;
-#ifndef NEW_TIMER_SYSTEM
-               jerry_i2s_exec(0);
-#else
                RemoveCallback(JERRYI2SCallback);
                JERRYI2SCallback();
-#endif
 
                DACWriteWord(offset, data, who);
                return;
@@ -856,8 +645,6 @@ else if (offset == 0xF10020)
        }
        else if (offset >= 0xF10000 && offset <= 0xF10007)
        {
-//#ifndef NEW_TIMER_SYSTEM
-#if 1
                switch(offset & 0x07)
                {
                case 0:
@@ -877,9 +664,7 @@ else if (offset == 0xF10020)
                        JERRYResetPIT2();
                }
                // Need to handle (unaligned) cases???
-#else
-WriteLog("JERRY: Unhandled timer write %04X (WORD) at %08X by %s...\n", data, offset, whoName[who]);
-#endif
+
                return;
        }
 /*     else if (offset >= 0xF10010 && offset < 0xF10016)
index 6d57ca3e09c0064c40fb8976069d169ac0854b16..64921476a00598e9707348ffad971f70054b2bba 100644 (file)
@@ -156,6 +156,8 @@ uint32 butch, dscntrl, ds_data, i2cntrl, sbcntrl, subdata, subdatb, sb_time, fif
 // Actually, considering that "byteswap.h" doesn't exist elsewhere, the above
 // is probably our best bet here. Just need to rename them to ESAFExx().
 
+// Look at <endian.h> and see if that header is portable or not.
+
 uint16 & memcon1   = *((uint16 *)&jagMemSpace[0xF00000]);
 uint16 & memcon2   = *((uint16 *)&jagMemSpace[0xF00002]);
 uint16 & hc        = *((uint16 *)&jagMemSpace[0xF00004]);