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
}
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;
// 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) * ();
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);
}
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 " : ""),
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__
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,
//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,
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:
#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();
// 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
{
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);
// 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 }
};
"<b>Bernd Schmidt</b> for his UAE 68K emulator<br>"
"<b>Sam Lantinga</b> for his amazing SDL libraries<br>"
"<b>Ryan C. Gordon</b> for Virtual Jaguar's web presence<br>"
- "<b>Curt Vendel</b> for various Jaguar & other goodies (you <i>rock!</i>)<br>"
+ "<b>Curt Vendel</b> for various Jaguar & other goodies<br>"
"<b>Reboot</b> for reasons too numerous to mention<br>"
"<b>The Free Jaguar Project</b> (you know why) ;-)<br>"
"The guys over at <b>Atari Age</b> :-)<br>"
uint32_t m68kSR = m68k_get_reg(NULL, M68K_REG_SR);
sprintf(string, "PC: %06X SR: %04X<br><br>", 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);
s += QString(string);
// GPU
- sprintf(string, "GPU PC: %06X FLAGS: %08X<br><br>", GPUReadLong(0xF02010), GPUReadLong(0xF02000));
+ sprintf(string, "GPU PC: %06X FLAGS: %04X SR: %04X<br><br>", 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:<br>"
"R00: %08X R01: %08X R02: %08X R03: %08X<br>"
s += QString(string);
// DSP
- sprintf(string, "DSP PC: %06X FLAGS: %08X<br><br>", DSPReadLong(0xF1A110), DSPReadLong(0xF1A100));
+ sprintf(string, "DSP PC: %06X FLAGS: %05X SR: %05X<br><br>", 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:<br>"
"R00: %08X R01: %08X R02: %08X R03: %08X<br>"
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);
}
}
-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);
}
+//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
{
GLWidget(QWidget * parent = 0);
~GLWidget();
+// void HideMouseIfTimedOut(void);
+ void HandleMouseHiding(void);
+ void CheckAndRestoreMouseCursor(void);
// QSize minimumSizeHint() const;
// QSize sizeHint() const;
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);
int offset;
bool fullscreen;
int outputWidth;
+ int32_t hideMouseTimeout;
};
#endif // __GLWIDGET_H__
//
// 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)
//
#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__
// Otherwise, run the Jaguar simulation
HandleGamepads();
JaguarExecuteNew();
+// videoWidget->HideMouseIfTimedOut();
+ videoWidget->HandleMouseHiding();
}
videoWidget->updateGL();
// 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);
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++)
{
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;
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)
{
private slots:
void Open(void);
- void Configure(void);
+ void Configure(void);
void Timer(void);
void TogglePowerState(void);
void ToggleRunState(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();
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...
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();
if (fp == NULL)
return;
- fwrite(jaguarMainRAM, 1, 0x400000, fp);
+ fwrite(jaguarMainRAM, 1, 0x200000, fp);
fclose(fp);
}
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;
{
//WriteLog("i2s: reseting\n");
//This is really SCLK... !!! FIX !!!
- JERRYI2SInterruptDivide = 8;
+ sclk = 8;
JERRYI2SInterruptTimer = -1;
}
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).
}
// 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)
{
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();
DACWriteWord(offset, data, who);
return;
}
+#endif
// LTXD/RTXD/SCLK/SMODE $F1A148/4C/50/54 (really 16-bit registers...)
else if (offset >= 0xF1A148 && offset <= 0xF1A156)
{
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));
}
+
// External variables
-extern uint32_t JERRYI2SInterruptDivide;
+//extern uint32_t JERRYI2SInterruptDivide;
extern int32_t JERRYI2SInterruptTimer;
#endif
// 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" };
// 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