From: Shamus Hammons Date: Thu, 7 Mar 2013 22:03:07 +0000 (-0600) Subject: Various changes to improve code readability, added mouse hiding. X-Git-Tag: 2.1.1~34 X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?p=virtualjaguar;a=commitdiff_plain;h=7228359373eb7602c26f7b098d6b2271ff5727a1 Various changes to improve code readability, added mouse hiding. First steps towards using the variables exposed in memory.cpp; there's still a long way to go. Reverted the instruction timings back to the old and incorrect shorter durations; this fixes sound in Rayman and FACTS. Also added mouse hiding: if the mouse is sitting on top of the VJ window and it hasn't moved in around a second, it is hidden until you move it again. This behaviour only happens when the emulated Jaguar is running; at all other times it is quiescent. --- diff --git a/src/dac.cpp b/src/dac.cpp index b7a7810..f082954 100644 --- a/src/dac.cpp +++ b/src/dac.cpp @@ -77,8 +77,8 @@ static SDL_AudioSpec desired; static bool SDLSoundInitialized; -static uint8_t SCLKFrequencyDivider = 19; // Default is roughly 22 KHz (20774 Hz in NTSC mode) -/*static*/ uint16_t serialMode = 0; +//static uint8_t SCLKFrequencyDivider = 19; // Default is roughly 22 KHz (20774 Hz in NTSC mode) +// /*static*/ uint16_t serialMode = 0; // Private function prototypes @@ -117,6 +117,7 @@ void DACInit(void) } ltxd = lrxd = desired.silence; + sclk = 19; // Default is roughly 22 KHz uint32_t riscClockRate = (vjs.hardwareTypeNTSC ? RISC_CLOCK_RATE_NTSC : RISC_CLOCK_RATE_PAL); uint32_t cyclesPerSample = riscClockRate / DAC_AUDIO_RATE; @@ -194,8 +195,8 @@ void SDLSoundCallback(void * userdata, Uint8 * buffer, int length) // 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; +// 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) * (); @@ -203,12 +204,14 @@ void SDLSoundCallback(void * userdata, Uint8 * buffer, int length) bufferIndex = 0; sampleBuffer = buffer; +// If length is the length of the sample buffer in BYTES, then shouldn't the # of +// samples be / 4? No, because we bump the sample count by 2, so this is OK. 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! + // These timings are tied to NTSC, need to fix that in event.cpp/h! [FIXED] do { double timeToNextEvent = GetTimeToNextEvent(EVENT_JERRY); @@ -281,14 +284,17 @@ void DACWriteWord(uint32_t offset, uint16_t data, uint32_t who/*= UNKNOWN*/) } else if (offset == SCLK + 2) // Sample rate { - WriteLog("DAC: Writing %u to SCLK...\n", data); + WriteLog("DAC: Writing %u to SCLK (by %s)...\n", data, whoName[who]); - if ((uint8_t)data != SCLKFrequencyDivider) - SCLKFrequencyDivider = (uint8_t)data; + sclk = data & 0xFF; + JERRYI2SInterruptTimer = -1; + RemoveCallback(JERRYI2SCallback); + JERRYI2SCallback(); } else if (offset == SMODE + 2) { - serialMode = data; +// serialMode = data; + smode = data; 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 " : ""), diff --git a/src/dac.h b/src/dac.h index 8149ff0..52a9324 100644 --- a/src/dac.h +++ b/src/dac.h @@ -20,4 +20,14 @@ void DACWriteWord(uint32_t offset, uint16_t data, uint32_t who = UNKNOWN); uint8_t DACReadByte(uint32_t offset, uint32_t who = UNKNOWN); uint16_t DACReadWord(uint32_t offset, uint32_t who = UNKNOWN); + +// DAC defines + +#define SMODE_INTERNAL 0x01 +#define SMODE_MODE 0x02 +#define SMODE_WSEN 0x04 +#define SMODE_RISING 0x08 +#define SMODE_FALLING 0x10 +#define SMODE_EVERYWORD 0x20 + #endif // __DAC_H__ diff --git a/src/dsp.cpp b/src/dsp.cpp index 53a7d08..748c4ab 100644 --- a/src/dsp.cpp +++ b/src/dsp.cpp @@ -310,7 +310,7 @@ static void dsp_opcode_subqmod(void); static void dsp_opcode_subqt(void); static void dsp_opcode_illegal(void); -uint8_t dsp_opcode_cycles[64] = +/*uint8_t dsp_opcode_cycles[64] = { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, @@ -325,7 +325,10 @@ uint8_t dsp_opcode_cycles[64] = //This is wrong, wrong, WRONG, but it seems to work for the time being... //(That is, it fixes Flip Out which relies on GPU timing rather than semaphores. Bad developers! Bad!) //What's needed here is a way to take pipeline effects into account (including pipeline stalls!)... -/*uint8_t dsp_opcode_cycles[64] = +// Yup, without cheating like this, the sound in things like Rayman, FACTS, & +// Tripper Getem get starved for time and sounds like crap. So we have to figure +// out how to fix that. :-/ +uint8_t dsp_opcode_cycles[64] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -755,80 +758,6 @@ SET32(ram2, offset, data); DSPUpdateRegisterBanks(); dsp_control &= ~((dsp_flags & CINT04FLAGS) >> 3); dsp_control &= ~((dsp_flags & CINT5FLAG) >> 1); - -// NB: This is just a wild hairy-assed guess as to what the playback frequency is. -// It can be timed to anything really, anything that writes to L/RTXD at a regular -// interval. Most things seem to use either the I2S interrupt or the TIMER 0 -// interrupt, so that's what we check for here. Just know that this approach -// can be easily fooled! -// Note also that if both interrupts are enabled, the I2S freq will win. :-P - -// Further Note: -// The impetus for this "fix" was Cybermorph, which sets the SCLK to 7 which is an -// audio frequency > 48 KHz. However, it stuffs the L/RTXD registers using TIMER0. -// So, while this works, it's a by-product of the lame way in which audio is currently -// handled. Hopefully, once we run the DSP in the host audio IRQ, this problem will -// go away of its own accord. :-P -// Or does it? It seems the I2S interrupt isn't on with Cybermorph, so something -// weird is going on here... -// Maybe it works like this: It acknowledges the 1st interrupt, but never clears it. -// So subsequent interrupts come into the chip, but they're never serviced but the -// I2S subsystem keeps going. -// After some testing on real hardware, it seems that if you enable TIMER0 and EXTERNAL -// IRQs on J_INT ($F10020), you don't have to run an I2S interrupt on the DSP. Also, -// It seems that it's only stable for values of SCLK <= 9. - -// All of the preceeding is moot now; we run the DSP in the host audio IRQ. This means -// that we don't actually need this stuff anymore. :-D -#if 0 - if (data & INT_ENA1) // I2S interrupt - { - int freq = GetCalculatedFrequency(); -//This happens too often to be useful... -// WriteLog("DSP: Setting audio freqency to %u Hz...\n", freq); - DACSetNewFrequency(freq); - } - else if (data & INT_ENA2) // TIMER 0 interrupt - { - int freq = JERRYGetPIT1Frequency(); -//This happens too often to be useful... -// WriteLog("DSP: Setting audio freqency to %u Hz...\n", freq); - DACSetNewFrequency(freq); - } -#endif - -/* if (IMASKCleared) // If IMASK was cleared, -#ifdef DSP_DEBUG_IRQ - { - WriteLog("DSP: Finished interrupt.\n"); -#endif - DSPHandleIRQs(); // see if any other interrupts need servicing! -#ifdef DSP_DEBUG_IRQ - } -#endif//*/ -#if 0 - if (/*4-8, 16*/data & 0x101F0) - WriteLog("DSP: %s is enabling interrupts %s%s%s%s%s%s\n", whoName[who], - (data & 0x010 ? "CPU " : ""), (data & 0x020 ? "I2S " : ""), - (data & 0x040 ? "TIMER0 " : ""), (data & 0x080 ? "TIMER1 " : ""), - (data & 0x100 ? "EXT0 " : ""), (data & 0x10000 ? "EXT1" : "")); -/*if (data & 0x00020) // CD BIOS DSP code... -{ -//001AC1BA: movea.l #$1AC200, A0 -//001AC1C0: move.l #$1AC68C, D0 - char buffer[512]; - - WriteLog("\n---[DSP code at 00F1B97C]---------------------------\n"); - uint32_t j = 0xF1B97C;//0x1AC200; - while (j <= 0xF1BE08)//0x1AC68C) - { - uint32_t oldj = j; - j += dasmjag(JAGUAR_DSP, buffer, j); -// WriteLog("\t%08X: %s\n", oldj+0xD6F77C, buffer); - WriteLog("\t%08X: %s\n", oldj, buffer); - } -}//*/ -#endif break; } case 0x04: @@ -867,10 +796,9 @@ WriteLog("Write to DSP CTRL by %s: %08X (DSP PC=$%08X)\n", whoName[who], data, d #ifdef DSP_DEBUG WriteLog("DSP: DSP -> CPU interrupt\n"); #endif -// This was WRONG -// Why do we check for a valid handler at 64? Isn't that the Jag programmer's responsibility? (YES) + #warning "!!! DSP IRQs that go to the 68K have to be routed thru TOM !!! FIX !!!" - if (JERRYIRQEnabled(IRQ2_DSP))// && jaguar_interrupt_handler_is_valid(64)) + if (JERRYIRQEnabled(IRQ2_DSP)) { JERRYSetPendingIRQ(IRQ2_DSP); DSPReleaseTimeslice(); diff --git a/src/event.cpp b/src/event.cpp index 6951d16..56e960d 100644 --- a/src/event.cpp +++ b/src/event.cpp @@ -37,7 +37,7 @@ // list. // Although if we used an insertion sort we could, but it wouldn't work for adjusting -// times... +// times... (For that, you would have to remove the event then reinsert it.) struct Event { diff --git a/src/event.h b/src/event.h index ff976c9..533783c 100644 --- a/src/event.h +++ b/src/event.h @@ -10,17 +10,17 @@ enum { EVENT_MAIN, EVENT_JERRY }; //NTSC Timings... -#define RISC_CYCLE_IN_USEC 0.03760684198 -#define M68K_CYCLE_IN_USEC (RISC_CYCLE_IN_USEC * 2) +#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 HORIZ_PERIOD_IN_USEC_NTSC 63.555555555 +#define HORIZ_PERIOD_IN_USEC_PAL 64.0 -#define USEC_TO_RISC_CYCLES(u) (uint32_t)(((u) / RISC_CYCLE_IN_USEC) + 0.5) -#define USEC_TO_M68K_CYCLES(u) (uint32_t)(((u) / M68K_CYCLE_IN_USEC) + 0.5) +#define USEC_TO_RISC_CYCLES(u) (uint32_t)(((u) / (vjs.hardwareTypeNTSC ? RISC_CYCLE_IN_USEC : RISC_CYCLE_PAL_IN_USEC)) + 0.5) +#define USEC_TO_M68K_CYCLES(u) (uint32_t)(((u) / (vjs.hardwareTypeNTSC ? M68K_CYCLE_IN_USEC : M68K_CYCLE_PAL_IN_USEC)) + 0.5) void InitializeEventList(void); void SetCallbackTime(void (* callback)(void), double time, int type = EVENT_MAIN); diff --git a/src/filedb.cpp b/src/filedb.cpp index e1deee3..ee12846 100644 --- a/src/filedb.cpp +++ b/src/filedb.cpp @@ -132,5 +132,6 @@ RomIdentifier romList[] = { // is this really a BIOS??? // No, it's really a cart, complete with RSA header. So need to fix so it can load. { 0xFDF37F47, "Memory Track Cartridge (World)", FF_ROM | FF_VERIFIED }, + { 0xF7756A03, "Tripper Getem (World)", FF_ROM | FF_VERIFIED }, { 0xFFFFFFFF, "***END***", 0 } }; diff --git a/src/gui/about.cpp b/src/gui/about.cpp index e56c165..879e977 100644 --- a/src/gui/about.cpp +++ b/src/gui/about.cpp @@ -49,7 +49,7 @@ AboutWindow::AboutWindow(QWidget * parent/*= 0*/): QWidget(parent, Qt::Dialog) "Bernd Schmidt for his UAE 68K emulator
" "Sam Lantinga for his amazing SDL libraries
" "Ryan C. Gordon for Virtual Jaguar's web presence
" - "Curt Vendel for various Jaguar & other goodies (you rock!)
" + "Curt Vendel for various Jaguar & other goodies
" "Reboot for reasons too numerous to mention
" "The Free Jaguar Project (you know why) ;-)
" "The guys over at Atari Age :-)
" diff --git a/src/gui/debug/cpubrowser.cpp b/src/gui/debug/cpubrowser.cpp index ac60638..daabbf3 100644 --- a/src/gui/debug/cpubrowser.cpp +++ b/src/gui/debug/cpubrowser.cpp @@ -56,6 +56,21 @@ void CPUBrowserWindow::RefreshContents(void) uint32_t m68kSR = m68k_get_reg(NULL, M68K_REG_SR); sprintf(string, "PC: %06X  SR: %04X

", m68kPC, m68kSR); s += QString(string); +/* +SR format: ++--+--+--+--+ +--+--+--+--+ +--+--+--+--+ +--+--+--+--+ +|T1|T0| S| M| |--|I2|I1|I0| |--|--|--| X| | N| Z| V| C| ++--+--+--+--+ +--+--+--+--+ +--+--+--+--+ +--+--+--+--+ + T - Trace (T1 only in 68K, T0 = 0) + S - Supervisor flag + M - Master/Interrupt flag (= 0 in 68K) + I - Interrupt level mask + X - Extend flag + N - Negative flag + Z - Zero flag + V - Overflow flag + C - Carry flag +*/ uint32_t m68kA0 = m68k_get_reg(NULL, M68K_REG_A0); uint32_t m68kA1 = m68k_get_reg(NULL, M68K_REG_A1); @@ -86,8 +101,30 @@ void CPUBrowserWindow::RefreshContents(void) s += QString(string); // GPU - sprintf(string, "GPU PC: %06X  FLAGS: %08X

", GPUReadLong(0xF02010), GPUReadLong(0xF02000)); + sprintf(string, "GPU PC: %06X  FLAGS: %04X  SR: %04X

", GPUReadLong(0xF02110, DEBUG), GPUReadLong(0xF02100, DEBUG), GPUReadLong(0xF02114, DEBUG)); s += QString(string); +/* +GPU Flags: +0 - Zero flag +1 - Carry flag +2 - Negative flag +3 - IMASK (writing 0 clears, 1 has no effect) +4-8 - IRQ enable 0 - 4 +9-13 - IRQ latch clear 0 - 4 +14 - REGPAGE +15 - DMAEN + +GPU Control: +0 - GPU Go +1 - CPUINT +2 - GPUINT0 +3 - Single Step +4 - Single step go +5 - Unused +6-10 - IRQ Latch 0 - 4 +11 - Bus Hog +12-15 - Version +*/ sprintf(string, "Bank 0:
" "R00: %08X  R01: %08X  R02: %08X  R03: %08X
" @@ -128,8 +165,33 @@ void CPUBrowserWindow::RefreshContents(void) s += QString(string); // DSP - sprintf(string, "DSP PC: %06X  FLAGS: %08X

", DSPReadLong(0xF1A110), DSPReadLong(0xF1A100)); + sprintf(string, "DSP PC: %06X  FLAGS: %05X  SR: %05X

", DSPReadLong(0xF1A110, DEBUG), DSPReadLong(0xF1A100, DEBUG), DSPReadLong(0xF1A114, DEBUG)); s += QString(string); +/* +DSP Flags: +0 - Zero flag +1 - Carry flag +2 - Negative flag +3 - IMASK (writing 0 clears, 1 has no effect) +4-8 - IRQ enable 0 - 4 +9-13 - IRQ latch clear 0 - 4 +14 - REGPAGE +15 - DMAEN +16 - IRQ enable 5 +17 - IRQ latch clear 5 + +DSP Control: +0 - DSP Go +1 - CPUINT +2 - DSPINT0 +3 - Single Step +4 - Single step go +5 - Unused +6-10 - IRQ Latch 0 - 4 +11 - Bus Hog +12-15 - Version +16 - IRQ Latch 5 +*/ sprintf(string, "Bank 0:
" "R00: %08X  R01: %08X  R02: %08X  R03: %08X
" diff --git a/src/gui/glwidget.cpp b/src/gui/glwidget.cpp index 058f9e0..2f95918 100644 --- a/src/gui/glwidget.cpp +++ b/src/gui/glwidget.cpp @@ -26,10 +26,11 @@ GLWidget::GLWidget(QWidget * parent/*= 0*/): QGLWidget(parent), texture(0), textureWidth(0), textureHeight(0), buffer(0), rasterWidth(326), rasterHeight(240), - offset(0) + offset(0), hideMouseTimeout(60) { // Screen pitch has to be the texture width (in 32-bit pixels)... JaguarSetScreenPitch(1024); + setMouseTracking(true); } @@ -113,7 +114,7 @@ void GLWidget::paintGL() } -void GLWidget::resizeGL(int width, int height) +void GLWidget::resizeGL(int /*width*/, int /*height*/) { //kludge [No, this is where it belongs!] rasterHeight = (vjs.hardwareTypeNTSC ? VIRTUAL_SCREEN_HEIGHT_NTSC : VIRTUAL_SCREEN_HEIGHT_PAL); @@ -143,6 +144,44 @@ void GLWidget::CreateTextures(void) } +//void GLWidget::HideMouseIfTimedOut(void) +void GLWidget::HandleMouseHiding(void) +{ + // Mouse watchdog timer handling. Basically, if the timeout value is + // greater than zero, decrement it. Otherwise, check for zero, if so, + // then hide the mouse and set the hideMouseTimeout value to -1 to + // signal that the mouse has been hidden. + if (hideMouseTimeout > 0) + hideMouseTimeout--; + else if (hideMouseTimeout == 0) + { + hideMouseTimeout--; + qApp->setOverrideCursor(Qt::BlankCursor); +//printf("timer: hideMouseTimeout = %i, mouse hidden\n", hideMouseTimeout); + } +} + + +// We use this as part of a watchdog system for hiding/unhiding the mouse. This +// part shows the mouse (if hidden) and resets the watchdog timer. +void GLWidget::CheckAndRestoreMouseCursor(void) +{ + // Has the mouse been hidden? (-1 means mouse was hidden) + if (hideMouseTimeout == -1) + qApp->restoreOverrideCursor(); + + hideMouseTimeout = 60; +} + + +// We check here for mouse movement; if there is any, show the mouse and reset +// the watchdog timer. +void GLWidget::mouseMoveEvent(QMouseEvent * /*event*/) +{ + CheckAndRestoreMouseCursor(); +} + + #if 0 class RubyGLWidget: public QGLWidget { diff --git a/src/gui/glwidget.h b/src/gui/glwidget.h index 1e8e113..40d2755 100644 --- a/src/gui/glwidget.h +++ b/src/gui/glwidget.h @@ -17,6 +17,9 @@ class GLWidget: public QGLWidget GLWidget(QWidget * parent = 0); ~GLWidget(); +// void HideMouseIfTimedOut(void); + void HandleMouseHiding(void); + void CheckAndRestoreMouseCursor(void); // QSize minimumSizeHint() const; // QSize sizeHint() const; @@ -27,6 +30,9 @@ class GLWidget: public QGLWidget void initializeGL(void); void paintGL(void); void resizeGL(int width, int height); + void mouseMoveEvent(QMouseEvent *); +// void mousePressEvent(QMouseEvent * event); +// void mouseReleaseEvent(QMouseEvent * event); private: void CreateTextures(void); @@ -43,6 +49,7 @@ class GLWidget: public QGLWidget int offset; bool fullscreen; int outputWidth; + int32_t hideMouseTimeout; }; #endif // __GLWIDGET_H__ diff --git a/src/gui/mainwin.cpp b/src/gui/mainwin.cpp index 0fde969..782eb25 100644 --- a/src/gui/mainwin.cpp +++ b/src/gui/mainwin.cpp @@ -21,6 +21,7 @@ // // STILL TO BE DONE: // +// - Fix bug in switching between PAL & NTSC in fullscreen mode. // - Remove SDL dependencies (sound, mainly) from Jaguar core lib // - Fix inconsistency with trailing slashes in paths (eeproms needs one, software doesn't) // @@ -59,6 +60,7 @@ #include "jagcdbios.h" #include "jagstub2bios.h" #include "joystick.h" +#include "m68000/m68kinterface.h" // According to SebRmv, this header isn't seen on Arch Linux either... :-/ //#ifdef __GCCWIN32__ @@ -651,6 +653,8 @@ void MainWin::Timer(void) // Otherwise, run the Jaguar simulation HandleGamepads(); JaguarExecuteNew(); +// videoWidget->HideMouseIfTimedOut(); + videoWidget->HandleMouseHiding(); } videoWidget->updateGL(); @@ -665,6 +669,8 @@ void MainWin::TogglePowerState(void) // With the power off, we simulate white noise on the screen. :-) if (!powerButtonOn) { + // Restore the mouse pointer, if hidden: + videoWidget->CheckAndRestoreMouseCursor(); useCDAct->setDisabled(false); palAct->setDisabled(false); ntscAct->setDisabled(false); @@ -720,6 +726,8 @@ void MainWin::ToggleRunState(void) if (!running) { + // Restore the mouse pointer, if hidden: + videoWidget->CheckAndRestoreMouseCursor(); frameAdvanceAct->setDisabled(false); for(uint32_t i=0; i<(uint32_t)(videoWidget->textureWidth * 256); i++) @@ -832,8 +840,6 @@ void MainWin::LoadSoftware(QString file) { running = false; // Prevent bad things(TM) from happening... pauseForFileSelector = false; // Reset the file selector pause flag - SET32(jaguarMainRAM, 0, 0x00200000); // Set top of stack... - cartridgeLoaded = JaguarLoadFile(file.toAscii().data()); char * biosPointer = jaguarBootROM; @@ -846,6 +852,16 @@ void MainWin::LoadSoftware(QString file) powerAct->setChecked(true); powerButtonOn = false; TogglePowerState(); + // We have to load our software *after* the Jaguar RESET + cartridgeLoaded = JaguarLoadFile(file.toAscii().data()); + SET32(jaguarMainRAM, 0, 0x00200000); // Set top of stack... + + // This is icky because we've already done it +// it gets worse :-P +if (!vjs.useJaguarBIOS) + SET32(jaguarMainRAM, 4, jaguarRunAddress); + + m68k_pulse_reset(); if (!vjs.hardwareTypeAlpine && !loadAndGo) { diff --git a/src/gui/mainwin.h b/src/gui/mainwin.h index 1c7871c..9efddfd 100644 --- a/src/gui/mainwin.h +++ b/src/gui/mainwin.h @@ -41,7 +41,7 @@ class MainWin: public QMainWindow private slots: void Open(void); - void Configure(void); + void Configure(void); void Timer(void); void TogglePowerState(void); void ToggleRunState(void); diff --git a/src/jaguar.cpp b/src/jaguar.cpp index e1b95aa..019ed6b 100644 --- a/src/jaguar.cpp +++ b/src/jaguar.cpp @@ -1777,13 +1777,12 @@ void JaguarInit(void) //NOTE: This *doesn't* fix FlipOut... //Or does it? Hmm... //Seems to want $01010101... Dunno why. Investigate! - memset(jaguarMainROM, 0x01, 0x600000); // & set it to all 01s... +// memset(jaguarMainROM, 0x01, 0x600000); // & set it to all 01s... // memset(jaguar_mainRom, 0xFF, 0x600000); // & set it to all Fs... lowerField = false; // Reset the lower field flag //temp, for crappy crap that sux memset(jaguarMainRAM + 0x804, 0xFF, 4); -// m68k_set_cpu_type(M68K_CPU_TYPE_68000); m68k_pulse_reset(); // Need to do this so UAE disasm doesn't segfault on exit GPUInit(); DSPInit(); @@ -1798,8 +1797,9 @@ void HalflineCallback(void); void RenderCallback(void); void JaguarReset(void) { + // Only problem with this approach: It wipes out RAM loaded files...! // Contents of local RAM are quasi-stable; we simulate this by randomizing RAM contents - for(uint32_t i=0; i<0x200000; i+=4) + for(uint32_t i=8; i<0x200000; i+=4) *((uint32_t *)(&jaguarMainRAM[i])) = rand(); // New timer base code stuffola... @@ -1927,12 +1927,6 @@ void JaguarDone(void) M68K_show_context(); //#endif -#if 0 // This is drawn already... - WriteLog("Jaguar: 68K AutoVector table:\n", JaguarReadWord(0x3004)); - for(uint32_t i=0x64; i<=0x7C; i+=4) - WriteLog(" #%u: %08X\n", (i-0x64)/4, JaguarReadLong(i)); -#endif - CDROMDone(); GPUDone(); DSPDone(); @@ -1991,7 +1985,7 @@ void DumpMainMemory(void) if (fp == NULL) return; - fwrite(jaguarMainRAM, 1, 0x400000, fp); + fwrite(jaguarMainRAM, 1, 0x200000, fp); fclose(fp); } diff --git a/src/jerry.cpp b/src/jerry.cpp index 8a27c31..9ff7ac6 100644 --- a/src/jerry.cpp +++ b/src/jerry.cpp @@ -185,7 +185,7 @@ static uint32_t JERRYPIT2Divider; static int32_t jerry_timer_1_counter; static int32_t jerry_timer_2_counter; -uint32_t JERRYI2SInterruptDivide = 8; +//uint32_t JERRYI2SInterruptDivide = 8; int32_t JERRYI2SInterruptTimer = -1; uint32_t jerryI2SCycles; uint32_t jerryIntPending; @@ -208,7 +208,7 @@ void JERRYResetI2S(void) { //WriteLog("i2s: reseting\n"); //This is really SCLK... !!! FIX !!! - JERRYI2SInterruptDivide = 8; + sclk = 8; JERRYI2SInterruptTimer = -1; } @@ -282,30 +282,30 @@ void JERRYPIT2Callback(void) void JERRYI2SCallback(void) { - // Why is it called this? Instead of SCLK? Shouldn't this be read from DAC.CPP??? -//Yes, it should. !!! FIX !!! -#warning "Why is it called this? Instead of SCLK? Shouldn't this be read from DAC.CPP??? Yes, it should. !!! FIX !!!" - JERRYI2SInterruptDivide &= 0xFF; // 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)); + jerryI2SCycles = 32 * (2 * (sclk + 1)); +//This makes audio faster, but not enough and the pitch is wrong besides +// jerryI2SCycles = 32 * (2 * (sclk - 1)); -//This should be in this file with an extern reference in the header file so that -//DAC.CPP can see it... !!! FIX !!! - extern uint16_t serialMode; // From DAC.CPP - - if (serialMode & 0x01) // INTERNAL flag (JERRY is master) + // If INTERNAL flag is set, then JERRY's SCLK is master + if (smode & SMODE_INTERNAL) { - DSPSetIRQLine(DSPIRQ_SSI, ASSERT_LINE); // This does the 'IRQ enabled' checking... - double usecs = (float)jerryI2SCycles * RISC_CYCLE_IN_USEC; + // This does the 'IRQ enabled' checking... + DSPSetIRQLine(DSPIRQ_SSI, ASSERT_LINE); +// double usecs = (float)jerryI2SCycles * RISC_CYCLE_IN_USEC; +//this fix is almost enough to fix timings in tripper, but not quite enough... + double usecs = (float)jerryI2SCycles * (vjs.hardwareTypeNTSC ? RISC_CYCLE_IN_USEC : RISC_CYCLE_PAL_IN_USEC); SetCallbackTime(JERRYI2SCallback, usecs, EVENT_JERRY); } - else // JERRY is slave to external word clock + else { + // JERRY is slave to external word clock + //Note that 44100 Hz requires samples every 22.675737 usec. //When JERRY is slave to the word clock, we need to do interrupts either at 44.1K //sample rate or at a 88.2K sample rate (11.332... usec). @@ -513,19 +513,25 @@ void JERRYWriteByte(uint32_t offset, uint8_t data, uint32_t who/*=UNKNOWN*/) } // SCLK ($F1A150--8 bits wide) //NOTE: This should be taken care of in DAC... +#if 0 else if ((offset >= 0xF1A152) && (offset <= 0xF1A153)) { +#if 0 // WriteLog("JERRY: Writing %02X to SCLK...\n", data); if ((offset & 0x03) == 2) - JERRYI2SInterruptDivide = (JERRYI2SInterruptDivide & 0x00FF) | ((uint32_t)data << 8); + sclk = (sclk & 0x00FF) | ((uint32_t)data << 8); else - JERRYI2SInterruptDivide = (JERRYI2SInterruptDivide & 0xFF00) | (uint32_t)data; - + sclk = (sclk & 0xFF00) | (uint32_t)data; +#else + sclk = data; +#endif +#warning "!!! SCLK should be handled in dac.cpp !!!" JERRYI2SInterruptTimer = -1; RemoveCallback(JERRYI2SCallback); JERRYI2SCallback(); // return; } +#endif // LTXD/RTXD/SCLK/SMODE $F1A148/4C/50/54 (really 16-bit registers...) else if (offset >= 0xF1A148 && offset <= 0xF1A157) { @@ -625,11 +631,17 @@ else if (offset == 0xF10020) return; } //NOTE: This should be taken care of in DAC... +#if 0 else if (offset == 0xF1A152) // Bottom half of SCLK ($F1A150) { +#warning "!!! SCLK should be handled in dac.cpp !!!" WriteLog("JERRY: Writing $%X to SCLK (by %s)...\n", data, whoName[who]); //This should *only* be enabled when SMODE has its INTERNAL bit set! !!! FIX !!! - JERRYI2SInterruptDivide = (uint8_t)data; +#if 0 + sclk = (uint8_t)data; +#else + sclk = data & 0xFF; +#endif JERRYI2SInterruptTimer = -1; RemoveCallback(JERRYI2SCallback); JERRYI2SCallback(); @@ -637,6 +649,7 @@ else if (offset == 0xF10020) DACWriteWord(offset, data, who); return; } +#endif // LTXD/RTXD/SCLK/SMODE $F1A148/4C/50/54 (really 16-bit registers...) else if (offset >= 0xF1A148 && offset <= 0xF1A156) { @@ -707,14 +720,17 @@ else if (offset == 0xF10020) jerry_ram_8[(offset+1) & 0xFFFF] = data & 0xFF; } + int JERRYGetPIT1Frequency(void) { int systemClockFrequency = (vjs.hardwareTypeNTSC ? RISC_CLOCK_RATE_NTSC : RISC_CLOCK_RATE_PAL); return systemClockFrequency / ((JERRYPIT1Prescaler + 1) * (JERRYPIT1Divider + 1)); } + int JERRYGetPIT2Frequency(void) { int systemClockFrequency = (vjs.hardwareTypeNTSC ? RISC_CLOCK_RATE_NTSC : RISC_CLOCK_RATE_PAL); return systemClockFrequency / ((JERRYPIT2Prescaler + 1) * (JERRYPIT2Divider + 1)); } + diff --git a/src/jerry.h b/src/jerry.h index 228c7ee..cff1c25 100644 --- a/src/jerry.h +++ b/src/jerry.h @@ -37,7 +37,7 @@ void JERRYI2SCallback(void); // External variables -extern uint32_t JERRYI2SInterruptDivide; +//extern uint32_t JERRYI2SInterruptDivide; extern int32_t JERRYI2SInterruptTimer; #endif diff --git a/src/memory.cpp b/src/memory.cpp index 03ba217..7ebdb2f 100644 --- a/src/memory.cpp +++ b/src/memory.cpp @@ -262,6 +262,5 @@ uint32_t & smode = *((uint32_t *)&jagMemSpace[0xF1A154]); // Memory debugging identifiers -const char * whoName[9] = - { "Unknown", "Jaguar", "DSP", "GPU", "TOM", "JERRY", "M68K", "Blitter", "OP" }; - +const char * whoName[10] = + { "Unknown", "Jaguar", "DSP", "GPU", "TOM", "JERRY", "M68K", "Blitter", "OP", "Debugger" }; diff --git a/src/memory.h b/src/memory.h index 81f96c9..0f84b7a 100644 --- a/src/memory.h +++ b/src/memory.h @@ -65,8 +65,8 @@ uint32_t & smode = *((uint32_t *)&jagMemSpace[0xF1A154]); // Read/write tracing enumeration -enum { UNKNOWN, JAGUAR, DSP, GPU, TOM, JERRY, M68K, BLITTER, OP }; -extern const char * whoName[9]; +enum { UNKNOWN, JAGUAR, DSP, GPU, TOM, JERRY, M68K, BLITTER, OP, DEBUG }; +extern const char * whoName[10]; // BIOS identification enum