]> Shamusworld >> Repos - virtualjaguar/blobdiff - src/tom.cpp
Fixed OP regression in Rayman, probably others.
[virtualjaguar] / src / tom.cpp
index 4b109b46965cc4b46c527e471347d7c8177b019f..046547248d5c41372490a2a99784e7fa476ee179 100644 (file)
 #include "log.h"
 #include "m68k.h"
 //#include "memory.h"
-#include "objectp.h"
+#include "op.h"
 #include "settings.h"
-#include "video.h"
 
 #define NEW_TIMER_SYSTEM
 
 #define VDB                    0x46
 #define VDE                    0x48
 #define VI                     0x4E
+#define PIT0           0x50
+#define PIT1           0x52
 #define BG                     0x58
 #define INT1           0xE0
 
@@ -697,7 +698,7 @@ void tom_render_24bpp_scanline(uint32 * backbuffer)
                current_line_buffer++;
                uint32 b = *current_line_buffer++;
 //hm.          *backbuffer++ = 0xFF000000 | (b << 16) | (g << 8) | r;
-               *backbuffer++ = 0x000000FF | (r << 24) | (g << 16) | (r << 8);
+               *backbuffer++ = 0x000000FF | (r << 24) | (g << 16) | (b << 8);
                width--;
        }
 }
@@ -771,6 +772,11 @@ void TOMExecScanline(uint16 scanline, bool render)
        if (scanline & 0x01)                                                    // Execute OP only on even lines (non-interlaced only!)
                return;
 
+//Hm, it seems that the OP needs to execute from zero, so let's try it:
+// And it works! But need to do some optimizations in the OP to keep it from attempting
+// to do a scanline render in the non-display area... [DONE]
+//this seems to cause a regression in certain games, like rayman
+#if 1
        if (scanline >= (uint16)GET16(tomRam8, VDB) && scanline < (uint16)GET16(tomRam8, VDE))
        {
                if (render)
@@ -788,6 +794,29 @@ void TOMExecScanline(uint16 scanline, bool render)
        }
        else
                inActiveDisplayArea = false;
+#else
+       inActiveDisplayArea =
+               (scanline >= (uint16)GET16(tomRam8, VDB) && scanline < (uint16)GET16(tomRam8, VDE)
+                       ? true : false);
+
+       if (scanline < (uint16)GET16(tomRam8, VDE))
+       {
+               if (render)//With JaguarExecuteNew() this is always true...
+               {
+                       uint8 * current_line_buffer = (uint8 *)&tomRam8[0x1800];
+                       uint8 bgHI = tomRam8[BG], bgLO = tomRam8[BG + 1];
+
+                       // Clear line buffer with BG
+                       if (GET16(tomRam8, VMODE) & BGEN) // && (CRY or RGB16)...
+                               for(uint32 i=0; i<720; i++)
+                                       *current_line_buffer++ = bgHI, *current_line_buffer++ = bgLO;
+
+//                     OPProcessList(scanline, render);
+//This seems to take care of it...
+                       OPProcessList(scanline, inActiveDisplayArea);
+               }
+       }
+#endif
 
        // Try to take PAL into account...
 
@@ -1072,7 +1101,7 @@ uint8 TOMReadByte(uint32 offset, uint32 who/*=UNKNOWN*/)
 //     offset &= 0xFF3FFF;
 
 #ifdef TOM_DEBUG
-       WriteLog("TOM: Reading byte at %06X\n", offset);
+       WriteLog("TOM: Reading byte at %06X for %s\n", offset, whoName[who]);
 #endif
 
        if ((offset >= GPU_CONTROL_RAM_BASE) && (offset < GPU_CONTROL_RAM_BASE+0x20))
@@ -1103,13 +1132,14 @@ uint16 TOMReadWord(uint32 offset, uint32 who/*=UNKNOWN*/)
 //???Is this needed???
 //     offset &= 0xFF3FFF;
 #ifdef TOM_DEBUG
-       WriteLog("TOM: Reading word at %06X\n", offset);
+       WriteLog("TOM: Reading word at %06X for %s\n", offset, whoName[who]);
 #endif
 if (offset >= 0xF02000 && offset <= 0xF020FF)
        WriteLog("TOM: Read attempted from GPU register file by %s (unimplemented)!\n", whoName[who]);
 
        if (offset == 0xF000E0)
        {
+               // For reading, should only return the lower 5 bits...
                uint16 data = (tom_jerry_int_pending << 4) | (tom_timer_int_pending << 3)
                        | (tom_object_int_pending << 2) | (tom_gpu_int_pending << 1)
                        | (tom_video_int_pending << 0);
@@ -1151,17 +1181,33 @@ if (offset >= 0xF02000 && offset <= 0xF020FF)
        return (TOMReadByte(offset, who) << 8) | TOMReadByte(offset + 1, who);
 }
 
+#define TOM_STRICT_MEMORY_ACCESS
 //
 // TOM byte access (write)
 //
 void TOMWriteByte(uint32 offset, uint8 data, uint32 who/*=UNKNOWN*/)
 {
+#ifdef TOM_DEBUG
+       WriteLog("TOM: Writing byte %02X at %06X", data, offset);
+#endif
 //???Is this needed???
 // Perhaps on the writes--32-bit writes that is! And masked with FF7FFF...
+#ifndef TOM_STRICT_MEMORY_ACCESS
        offset &= 0xFF3FFF;
-
+#else
+       // "Fast" (32-bit only) write access to the GPU
+//     if ((offset >= 0xF0A100) && (offset <= 0xF0BFFF))
+       if ((offset >= 0xF08000) && (offset <= 0xF0BFFF))
+               offset &= 0xFF7FFF;
+#endif
 #ifdef TOM_DEBUG
-       WriteLog("TOM: Writing byte %02X at %06X\n", data, offset);
+       WriteLog(" -->[%06X] by %s\n", offset, whoName[who]);
+#endif
+
+#ifdef TOM_STRICT_MEMORY_ACCESS
+       // Sanity check ("Aww, there ain't no Sanity Clause...")
+       if ((offset < 0xF00000) || (offset > 0xF03FFF))
+               return;
 #endif
 
        if ((offset >= GPU_CONTROL_RAM_BASE) && (offset < GPU_CONTROL_RAM_BASE+0x20))
@@ -1223,12 +1269,28 @@ void TOMWriteByte(uint32 offset, uint8 data, uint32 who/*=UNKNOWN*/)
 //
 void TOMWriteWord(uint32 offset, uint16 data, uint32 who/*=UNKNOWN*/)
 {
-//???Is this needed???
+#ifdef TOM_DEBUG
+       WriteLog("TOM: Writing byte %04X at %06X", data, offset);
+#endif
+//???Is this needed??? Yes, but we need to be more vigilant than this.
+#ifndef TOM_STRICT_MEMORY_ACCESS
        offset &= 0xFF3FFF;
-
+#else
+       // "Fast" (32-bit only) write access to the GPU
+//     if ((offset >= 0xF0A100) && (offset <= 0xF0BFFF))
+       if ((offset >= 0xF08000) && (offset <= 0xF0BFFF))
+               offset &= 0xFF7FFF;
+#endif
 #ifdef TOM_DEBUG
-       WriteLog("TOM: Writing word %04X at %06X\n", data, offset);
+       WriteLog(" -->[%06X] by %s\n", offset, whoName[who]);
+#endif
+
+#ifdef TOM_STRICT_MEMORY_ACCESS
+       // Sanity check
+       if ((offset < 0xF00000) || (offset > 0xF03FFF))
+               return;
 #endif
+
 if (offset == 0xF00000 + MEMCON1)
        WriteLog("TOM: Memory Configuration 1 written by %s: %04X\n", whoName[who], data);
 if (offset == 0xF00000 + MEMCON2)
@@ -1282,6 +1344,8 @@ if (offset >= 0xF02000 && offset <= 0xF020FF)
                        tom_timer_int_pending = 0;
                if (data & 0x1000)
                        tom_jerry_int_pending = 0;
+
+//             return;
        }
        else if ((offset >= 0xF02200) && (offset <= 0xF0229F))
        {
@@ -1293,6 +1357,7 @@ if (offset >= 0xF02000 && offset <= 0xF020FF)
                // Writing to one CLUT writes to the other
                offset &= 0x5FF;                // Mask out $F00600 (restrict to $F00400-5FF)
 // Watch out for unaligned writes here! (Not fixed yet)
+#warning "!!! Watch out for unaligned writes here !!! FIX !!!"
                SET16(tomRam8, offset, data);
                SET16(tomRam8, offset + 0x200, data);
        }
@@ -1308,8 +1373,9 @@ if (offset >= 0xF02000 && offset <= 0xF020FF)
        if (offset == 0x2E || offset == 0x36 || offset == 0x54)
                data &= 0x03FF;                 // These are all 10-bit registers
 
-       TOMWriteByte(offset, data >> 8, who);
-       TOMWriteByte(offset+1, data & 0xFF, who);
+// Fix a lockup bug... :-P
+       TOMWriteByte(0xF00000 | offset, data >> 8, who);
+       TOMWriteByte(0xF00000 | (offset+1), data & 0xFF, who);
 
 if (offset == VDB)
        WriteLog("TOM: Vertical Display Begin written by %s: %u\n", whoName[who], data);
@@ -1337,10 +1403,21 @@ if (offset == HBE)
        WriteLog("TOM: Horizontal Blank End written by %s: %u\n", whoName[who], data);
 if (offset == VMODE)
        WriteLog("TOM: Video Mode written by %s: %04X. PWIDTH = %u, MODE = %s, flags:%s%s (VC = %u)\n", whoName[who], data, ((data >> 9) & 0x07) + 1, videoMode_to_str[(data & MODE) >> 1], (data & BGEN ? " BGEN" : ""), (data & VARMOD ? " VARMOD" : ""), GET16(tomRam8, VC));
+if (offset == PIT0)
+       WriteLog("TOM: PIT0 written by %s: %u\n", whoName[who], data);
+if (offset == PIT1)
+       WriteLog("TOM: PIT1 written by %s: %u\n", whoName[who], data);
+//if (offset == INT1)
+//     WriteLog("TOM: CPU Interrupt Control written by %s: $%04X (%s%s%s%s%s)\n", whoName[who], data, (data & 0x01 ? "Video" : ""), (data & 0x02 ? " GPU" : ""), (data & 0x04 ? " OP" : ""), (data & 0x08 ? " TOMPIT" : ""), (data & 0x10 ? " Jerry" : ""));
 
        // detect screen resolution changes
 //This may go away in the future, if we do the virtualized screen thing...
 //This may go away soon!
+// TOM Shouldn't be mucking around with this, it's up to the host system to properly
+// handle this kind of crap.
+// NOTE: This is needed somehow, need to get rid of the dependency on this crap.
+#warning "!!! Need to get rid of this dependency !!!"
+#if 1
        if ((offset >= 0x28) && (offset <= 0x4F))
        {
                uint32 width = TOMGetVideoModeWidth(), height = TOMGetVideoModeHeight();
@@ -1355,6 +1432,7 @@ if (offset == VMODE)
 //                             ResizeScreen(tomWidth, tomHeight);
                }
        }
+#endif
 }
 
 int TOMIRQEnabled(int irq)
@@ -1411,7 +1489,7 @@ void TOMExecPIT(uint32 cycles)
                        GPUSetIRQLine(GPUIRQ_TIMER, ASSERT_LINE);       // GPUSetIRQLine does the 'IRQ enabled' checking
 
                        if (TOMIRQEnabled(IRQ_TIMER))
-                               m68k_set_irq(7);                                // Cause a 68000 NMI...
+                               m68k_set_irq(2);                                // Cause a 68000 IPL 2...
 
                        TOMResetPIT();
                }
@@ -1426,7 +1504,7 @@ void TOMPITCallback(void)
 
 //     if (INT1_WREG & 0x08)
        if (TOMIRQEnabled(IRQ_TIMER))
-               m68k_set_irq(7);                                                // Generate 68K NMI
+               m68k_set_irq(2);                                                // Generate a 68K IPL 2...
 
        TOMResetPIT();
 }