]> Shamusworld >> Repos - virtualjaguar/blobdiff - src/jerry.cpp
Preliminary support for passing in filenames from the command line.
[virtualjaguar] / src / jerry.cpp
index 671b08afdf2741458bf359dec086d345fc45ac3b..cba9571c808a666326dc71e58dab7e7a383767ed 100644 (file)
@@ -3,9 +3,9 @@
 //
 // Originally by David Raingeard
 // GCC/SDL port by Niels Wagenaar (Linux/WIN32) and Carwin Jones (BeOS)
-// Cleanups/rewrites/fixes by James L. Hammons
+// Cleanups/rewrites/fixes by James Hammons
 //
-// JLH = James L. Hammons
+// JLH = James Hammons <jlhamm@acm.org>
 //
 // WHO  WHEN        WHAT
 // ---  ----------  -----------------------------------------------------------
 #include "jaguar.h"
 #include "joystick.h"
 #include "log.h"
+#include "m68k.h"
+#include "settings.h"
+#include "tom.h"
 //#include "memory.h"
 #include "wavetable.h"
 
@@ -188,6 +191,8 @@ int32 JERRYI2SInterruptTimer = -1;
 uint32 jerryI2SCycles;
 uint32 jerryIntPending;
 
+static uint16 jerryInterruptMask = 0;
+static uint16 jerryPendingInterrupt = 0;
 // Private function prototypes
 
 void JERRYResetPIT1(void);
@@ -349,14 +354,43 @@ void JERRYResetPIT2(void)
 #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
 void JERRYPIT1Callback(void)
 {
+#ifndef JERRY_NO_IRQS
+//WriteLog("JERRY: In PIT1 callback, IRQM=$%04X\n", jerryInterruptMask);
+       if (TOMIRQEnabled(IRQ_DSP))
+       {
+               if (jerryInterruptMask & IRQ2_TIMER1)           // CPU Timer 1 IRQ
+               {
+// Not sure, but I think we don't generate another IRQ if one's already going...
+// But this seems to work... :-/
+                       jerryPendingInterrupt |= IRQ2_TIMER1;
+                       m68k_set_irq(2);                                                // Generate 68K IPL 2
+               }
+       }
+#endif
+
        DSPSetIRQLine(DSPIRQ_TIMER0, ASSERT_LINE);      // This does the 'IRQ enabled' checking...
        JERRYResetPIT1();
 }
 
 void JERRYPIT2Callback(void)
 {
+#ifndef JERRY_NO_IRQS
+       if (TOMIRQEnabled(IRQ_DSP))
+       {
+//WriteLog("JERRY: In PIT2 callback, IRQM=$%04X\n", jerryInterruptMask);
+               if (jerryInterruptMask & IRQ2_TIMER2)           // CPU Timer 2 IRQ
+               {
+                       jerryPendingInterrupt |= IRQ2_TIMER2;
+                       m68k_set_irq(2);                                                // Generate 68K IPL 2
+               }
+       }
+#endif
+
        DSPSetIRQLine(DSPIRQ_TIMER1, ASSERT_LINE);      // This does the 'IRQ enabled' checking...
        JERRYResetPIT2();
 }
@@ -422,25 +456,20 @@ void JERRYI2SCallback(void)
 
 void JERRYInit(void)
 {
-//     clock_init();
-//     anajoy_init();
        JoystickInit();
        DACInit();
-//This should be handled with the cart initialization...
-//     eeprom_init();
-//     memory_malloc_secure((void **)&jerry_ram_8, 0x10000, "JERRY RAM/ROM");
        memcpy(&jerry_ram_8[0xD000], waveTableROM, 0x1000);
 
        JERRYPIT1Prescaler = 0xFFFF;
        JERRYPIT2Prescaler = 0xFFFF;
        JERRYPIT1Divider = 0xFFFF;
        JERRYPIT2Divider = 0xFFFF;
+       jerryInterruptMask = 0x0000;
+       jerryPendingInterrupt = 0x0000;
 }
 
 void JERRYReset(void)
 {
-//     clock_reset();
-//     anajoy_reset();
        JoystickReset();
        EepromReset();
        JERRYResetI2S();
@@ -453,14 +482,13 @@ void JERRYReset(void)
        JERRYPIT2Divider = 0xFFFF;
        jerry_timer_1_counter = 0;
        jerry_timer_2_counter = 0;
+       jerryInterruptMask = 0x0000;
+       jerryPendingInterrupt = 0x0000;
 }
 
 void JERRYDone(void)
 {
        WriteLog("JERRY: M68K Interrupt control ($F10020) = %04X\n", GET16(jerry_ram_8, 0x20));
-//     memory_free(jerry_ram_8);
-//     clock_done();
-//     anajoy_done();
        JoystickDone();
        DACDone();
        EepromDone();
@@ -469,13 +497,15 @@ void JERRYDone(void)
 bool JERRYIRQEnabled(int irq)
 {
        // Read the word @ $F10020
-       return jerry_ram_8[0x21] & (1 << irq);
+//     return jerry_ram_8[0x21] & (1 << irq);
+       return jerryInterruptMask & irq;
 }
 
 void JERRYSetPendingIRQ(int irq)
 {
        // This is the shadow of INT (it's a split RO/WO register)
-       jerryIntPending |= (1 << irq);
+//     jerryIntPending |= (1 << irq);
+       jerryPendingInterrupt |= irq;
 }
 
 //
@@ -612,7 +642,8 @@ WriteLog("JERRY: Unhandled timer read (WORD) at %08X...\n", offset);
 //     else if ((offset >= 0xF10010) && (offset <= 0xF10015))
 //             return clock_word_read(offset);
        else if (offset == 0xF10020)
-               return jerryIntPending;
+//             return jerryIntPending;
+               return jerryPendingInterrupt;
 //     else if ((offset >= 0xF17C00) && (offset <= 0xF17C01))
 //             return anajoy_word_read(offset);
        else if (offset == 0xF14000)
@@ -720,9 +751,17 @@ WriteLog("JERRY: Unhandled timer write (BYTE) at %08X...\n", offset);
                return;
        }//*/
        // JERRY -> 68K interrupt enables/latches (need to be handled!)
-       else if (offset >= 0xF10020 && offset <= 0xF10023)
+       else if (offset >= 0xF10020 && offset <= 0xF10021)//WAS:23)
        {
-WriteLog("JERRY: (68K int en/lat - Unhandled!) Tried to write $%02X to $%08X!\n", data, offset);
+               if (offset == 0xF10020)
+               {
+                       // Clear pending interrupts...
+                       jerryPendingInterrupt &= ~data;
+               }
+               else if (offset == 0xF10021)
+                       jerryInterruptMask = data;
+//WriteLog("JERRY: (68K int en/lat - Unhandled!) Tried to write $%02X to $%08X!\n", data, offset);
+//WriteLog("JERRY: (Previous is partially handled... IRQMask=$%04X)\n", jerryInterruptMask);
        }
 /*     else if ((offset >= 0xF17C00) && (offset <= 0xF17C01))
        {
@@ -755,6 +794,28 @@ void JERRYWriteWord(uint32 offset, uint16 data, uint32 who/*=UNKNOWN*/)
 {
 #ifdef JERRY_DEBUG
        WriteLog( "JERRY: Writing word %04X at %06X\n", data, offset);
+#endif
+#if 1
+if (offset == 0xF10000)
+       WriteLog("JERRY: JPIT1 word written by %s: %u\n", whoName[who], data);
+else if (offset == 0xF10002)
+       WriteLog("JERRY: JPIT2 word written by %s: %u\n", whoName[who], data);
+else if (offset == 0xF10004)
+       WriteLog("JERRY: JPIT3 word written by %s: %u\n", whoName[who], data);
+else if (offset == 0xF10006)
+       WriteLog("JERRY: JPIT4 word written by %s: %u\n", whoName[who], data);
+else if (offset == 0xF10010)
+       WriteLog("JERRY: CLK1 word written by %s: %u\n", whoName[who], data);
+else if (offset == 0xF10012)
+       WriteLog("JERRY: CLK2 word written by %s: %u\n", whoName[who], data);
+else if (offset == 0xF10014)
+       WriteLog("JERRY: CLK3 word written by %s: %u\n", whoName[who], data);
+//else if (offset == 0xF1A100)
+//     WriteLog("JERRY: D_FLAGS word written by %s: %u\n", whoName[who], data);
+//else if (offset == 0xF1A102)
+//     WriteLog("JERRY: D_FLAGS+2 word written by %s: %u\n", whoName[who], data);
+//else if (offset == 0xF10020)
+//     WriteLog("JERRY: JINTCTRL word written by %s: $%04X\n", whoName[who], data);
 #endif
 
        if ((offset >= DSP_CONTROL_RAM_BASE) && (offset < DSP_CONTROL_RAM_BASE+0x20))
@@ -770,7 +831,7 @@ void JERRYWriteWord(uint32 offset, uint16 data, uint32 who/*=UNKNOWN*/)
 //NOTE: This should be taken care of in DAC...
        else if (offset == 0xF1A152)                                    // Bottom half of SCLK ($F1A150)
        {
-               WriteLog("JERRY: Writing %04X to SCLK (by %s)...\n", data, whoName[who]);
+               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)data;
                JERRYI2SInterruptTimer = -1;
@@ -826,7 +887,11 @@ WriteLog("JERRY: Unhandled timer write %04X (WORD) at %08X by %s...\n", data, of
        // JERRY -> 68K interrupt enables/latches (need to be handled!)
        else if (offset >= 0xF10020 && offset <= 0xF10022)
        {
-WriteLog("JERRY: (68K int en/lat - Unhandled!) Tried to write $%04X to $%08X!\n", data, offset);
+               jerryInterruptMask = data & 0xFF;
+               jerryPendingInterrupt &= ~(data >> 8);
+//WriteLog("JERRY: (68K int en/lat - Unhandled!) Tried to write $%04X to $%08X!\n", data, offset);
+//WriteLog("JERRY: (Previous is partially handled... IRQMask=$%04X)\n", jerryInterruptMask);
+               return;
        }
 /*     else if (offset >= 0xF17C00 && offset < 0xF17C02)
        {
@@ -853,3 +918,15 @@ WriteLog("JERRY: (68K int en/lat - Unhandled!) Tried to write $%04X to $%08X!\n"
        jerry_ram_8[(offset+0) & 0xFFFF] = (data >> 8) & 0xFF;
        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));
+}