X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fdac.cpp;h=02baf6c1717e04758e96d2b29d79e7b4609b2592;hb=a406fffa6c13391e497e4b66397b6e0358f3ffa8;hp=4e35d3bbb0b0e3e540a37c17bce2c49666cff63f;hpb=4ff423c8b9d28ce594f33574959f4fc78a4d417c;p=virtualjaguar diff --git a/src/dac.cpp b/src/dac.cpp index 4e35d3b..02baf6c 100644 --- a/src/dac.cpp +++ b/src/dac.cpp @@ -1,13 +1,13 @@ // // DAC (really, Synchronous Serial Interface) Handler // -// Original by Cal2 +// Originally by David Raingeard // GCC/SDL port by Niels Wagenaar (Linux/WIN32) and Caz (BeOS) // Rewritten by James L. Hammons // -//#include #include "SDL.h" +#include "m68k.h" #include "jaguar.h" #include "settings.h" #include "dac.h" @@ -20,20 +20,27 @@ #define LTXD 0xF1A148 #define RTXD 0xF1A14C +#define LRXD 0xF1A148 +#define RRXD 0xF1A14C #define SCLK 0xF1A150 #define SMODE 0xF1A154 +// Global variables + +uint16 lrxd, rrxd; // I2S ports (into Jaguar) + // Local variables -uint32 LeftFIFOHeadPtr, LeftFIFOTailPtr, RightFIFOHeadPtr, RightFIFOTailPtr; -SDL_AudioSpec desired; +static uint32 LeftFIFOHeadPtr, LeftFIFOTailPtr, RightFIFOHeadPtr, RightFIFOTailPtr; +static SDL_AudioSpec desired; +static bool SDLSoundInitialized = false; // We can get away with using native endian here because we can tell SDL to use the native // endian when looking at the sample buffer, i.e., no need to worry about it. -uint16 * DACBuffer; -uint8 SCLKFrequencyDivider = 19; // Default is roughly 22 KHz (20774 Hz in NTSC mode) -uint16 serialMode = 0; +static uint16 * DACBuffer; +static uint8 SCLKFrequencyDivider = 19; // Default is roughly 22 KHz (20774 Hz in NTSC mode) +/*static*/ uint16 serialMode = 0; // Private function prototypes @@ -56,14 +63,18 @@ void DACInit(void) if (SDL_OpenAudio(&desired, NULL) < 0) // NULL means SDL guarantees what we want { - WriteLog("DAC: Failed to initialize SDL sound. Shutting down!\n"); - log_done(); - exit(1); +// WriteLog("DAC: Failed to initialize SDL sound. Shutting down!\n"); +// log_done(); +// exit(1); + WriteLog("DAC: Failed to initialize SDL sound...\n"); + } + else + { + SDLSoundInitialized = true; + DACReset(); + SDL_PauseAudio(false); // Start playback! + WriteLog("DAC: Successfully initialized.\n"); } - - DACReset(); - SDL_PauseAudio(false); // Start playback! - WriteLog("DAC: Successfully initialized.\n"); } // @@ -79,8 +90,12 @@ void DACReset(void) // void DACDone(void) { - SDL_PauseAudio(true); - SDL_CloseAudio(); + if (SDLSoundInitialized) + { + SDL_PauseAudio(true); + SDL_CloseAudio(); + } + memory_free(DACBuffer); WriteLog("DAC: Done.\n"); } @@ -154,14 +169,14 @@ int GetCalculatedFrequency(void) // // LTXD/RTXD/SCLK/SMODE ($F1A148/4C/50/54) // -void DACWriteByte(uint32 offset, uint8 data) +void DACWriteByte(uint32 offset, uint8 data, uint32 who/*= UNKNOWN*/) { - WriteLog("DAC: Writing %02X at %08X\n", data, offset); + WriteLog("DAC: %s writing BYTE %02X at %08X\n", whoName[who], data, offset); if (offset == SCLK + 3) DACWriteWord(offset - 3, (uint16)data); } -void DACWriteWord(uint32 offset, uint16 data) +void DACWriteWord(uint32 offset, uint16 data, uint32 who/*= UNKNOWN*/) { if (offset == LTXD + 2) { @@ -216,43 +231,66 @@ if (spin == 0x10000000) //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! { - SDL_CloseAudio(); + if (SDLSoundInitialized) + SDL_CloseAudio(); + desired.freq = GetCalculatedFrequency();// SDL will do conversion on the fly, if it can't get the exact rate. Nice! WriteLog("DAC: Changing sample rate to %u Hz!\n", desired.freq); - if (SDL_OpenAudio(&desired, NULL) < 0) // NULL means SDL guarantees what we want + if (SDLSoundInitialized) { - WriteLog("DAC: Failed to initialize SDL sound: %s.\nDesired freq: %u\nShutting down!\n", SDL_GetError(), desired.freq); - log_done(); - exit(1); + if (SDL_OpenAudio(&desired, NULL) < 0) // NULL means SDL guarantees what we want + { + WriteLog("DAC: Failed to initialize SDL sound: %s.\nDesired freq: %u\nShutting down!\n", SDL_GetError(), desired.freq); + log_done(); + exit(1); + } } DACReset(); - SDL_PauseAudio(false); // Start playback! + + if (SDLSoundInitialized) + SDL_PauseAudio(false); // Start playback! } } } else if (offset == SMODE + 2) { serialMode = data; - WriteLog("DAC: Writing to SMODE. Bits: %s%s%s%s%s%s\n", + WriteLog("DAC: %s writing to SMODE. Bits: %s%s%s%s%s%s [68K PC=%08X]\n", whoName[who], (data & 0x01 ? "INTERNAL " : ""), (data & 0x02 ? "MODE " : ""), (data & 0x04 ? "WSEN " : ""), (data & 0x08 ? "RISING " : ""), - (data & 0x10 ? "FALLING " : ""), (data & 0x20 ? "EVERYWORD" : "")); + (data & 0x10 ? "FALLING " : ""), (data & 0x20 ? "EVERYWORD" : ""), + m68k_get_reg(NULL, M68K_REG_PC)); } } // // LRXD/RRXD/SSTAT ($F1A148/4C/50) // -uint8 DACReadByte(uint32 offset) +uint8 DACReadByte(uint32 offset, uint32 who/*= UNKNOWN*/) { -// WriteLog("DAC: Reading byte from %08X\n", offset); +// WriteLog("DAC: %s reading byte from %08X\n", whoName[who], offset); return 0xFF; } -uint16 DACReadWord(uint32 offset) +//static uint16 fakeWord = 0; +uint16 DACReadWord(uint32 offset, uint32 who/*= UNKNOWN*/) { -// WriteLog("DAC: Reading word from %08X\n", offset); - return 0xFFFF; +// WriteLog("DAC: %s reading word from %08X\n", whoName[who], offset); +// return 0xFFFF; +// WriteLog("DAC: %s reading WORD %04X from %08X\n", whoName[who], fakeWord, offset); +// return fakeWord++; +//NOTE: This only works if a bunch of things are set in BUTCH which we currently don't +// check for. !!! FIX !!! +// Partially fixed: We check for I2SCNTRL in the JERRY I2S routine... +// return GetWordFromButchSSI(offset, who); + if (offset == LRXD || offset == RRXD) + return 0x0000; + else if (offset == LRXD + 2) + return lrxd; + else if (offset == RRXD + 2) + return rrxd; + + return 0xFFFF; // May need SSTAT as well... (but may be a Jaguar II only feature) }