]> Shamusworld >> Repos - virtualjaguar/blobdiff - src/op.cpp
Added Object Processor browser window for debug mode.
[virtualjaguar] / src / op.cpp
index 778bf7465bfec870e8deb8e0f48e60fdfc2995d1..25322c91c6109b280bb2fbf01763924bce537e90 100644 (file)
@@ -20,7 +20,7 @@
 #include "gpu.h"
 #include "jaguar.h"
 #include "log.h"
-#include "m68k.h"
+#include "m68000/m68kinterface.h"
 #include "memory.h"
 #include "tom.h"
 
 #define OBJECT_TYPE_BRANCH     3                                       // 011
 #define OBJECT_TYPE_STOP       4                                       // 100
 
-#define CONDITION_EQUAL                                0
-#define CONDITION_LESS_THAN                    1
-#define CONDITION_GREATER_THAN         2
+#define CONDITION_EQUAL                                0                       // VC == YPOS
+#define CONDITION_LESS_THAN                    1                       // VC < YPOS
+#define CONDITION_GREATER_THAN         2                       // VC > YPOS
 #define CONDITION_OP_FLAG_SET          3
 #define CONDITION_SECOND_HALF_LINE     4
 
+#if 0
 #define OPFLAG_RELEASE         8                                       // Bus release bit
 #define OPFLAG_TRANS           4                                       // Transparency bit
 #define OPFLAG_RMW                     2                                       // Read-Modify-Write bit
 #define OPFLAG_REFLECT         1                                       // Horizontal mirror bit
+#endif
 
 // Private function prototypes
 
@@ -125,6 +127,7 @@ void OPInit(void)
        OPReset();
 }
 
+
 //
 // Object Processor reset
 //
@@ -134,6 +137,7 @@ void OPReset(void)
        objectp_running = 0;
 }
 
+
 static const char * opType[8] =
 { "(BITMAP)", "(SCALED BITMAP)", "(GPU INT)", "(BRANCH)", "(STOP)", "???", "???", "???" };
 static const char * ccType[8] =
@@ -143,6 +147,7 @@ static uint32 numberOfObjects;
 //static uint32 objectLink[8192];
 //static uint32 numberOfLinks;
 
+
 void OPDone(void)
 {
 //#warning "!!! Fix OL dump so that it follows links !!!"
@@ -180,27 +185,46 @@ void OPDone(void)
 
        WriteLog("\n");
 #else
+//#warning "!!! Fix lockup in OPDiscoverObjects() !!!"
+//temp, to keep the following function from locking up on bad/weird OLs
+//return;
+
        numberOfObjects = 0;
+//printf("OPDiscoverObjects...\n");
        OPDiscoverObjects(olp);
+//printf("OPDumpObjectList...\n");
        OPDumpObjectList();
 #endif
 }
 
-void OPDiscoverObjects(uint32 address)
+
+bool OPObjectExists(uint32 address)
 {
-       // Check to see if we've already seen this object
+       // Yes, we really do a linear search, every time. :-/
        for(uint32 i=0; i<numberOfObjects; i++)
        {
                if (address == object[i])
-                       return;
+                       return true;
        }
 
-       // Store the object...
-       object[numberOfObjects++] = address;
+       return false;
+}
+
+
+void OPDiscoverObjects(uint32 address)
+{
        uint8 objectType = 0;
 
        do
        {
+               // If we've seen this object already, bail out!
+               // Otherwise, add it to the list
+               if (OPObjectExists(address))
+                       return;
+
+               object[numberOfObjects++] = address;
+
+               // Get the object & decode its type, link address
                uint32 hi = JaguarReadLong(address + 0, OP);
                uint32 lo = JaguarReadLong(address + 4, OP);
                objectType = lo & 0x07;
@@ -208,39 +232,18 @@ void OPDiscoverObjects(uint32 address)
 
                if (objectType == 3)
                {
-                       uint16 ypos = (lo >> 3) & 0x7FF;
-                       uint8  cc   = (lo >> 14) & 0x07;        // Proper # of bits == 3
-
-                       // Recursion needed to follow all links!
+                       // Recursion needed to follow all links! This does depth-first recursion
+                       // on the not-taken objects
                        OPDiscoverObjects(address + 8);
                }
 
-               if (address == link)    // Ruh roh...
-               {
-                       // Runaway recursive link is bad!
-                       return;
-               }
-
+               // Get the next object...
                address = link;
-
-               // Check to see if we've already seen this object, and add it if not
-               bool seenObject = false;
-
-               for(uint32 i=0; i<numberOfObjects; i++)
-               {
-                       if (address == object[i])
-                       {
-                               seenObject = true;
-                               break;
-                       }
-               }
-
-               if (!seenObject)
-                       object[numberOfObjects++] = address;
        }
        while (objectType != 4);
 }
 
+
 void OPDumpObjectList(void)
 {
        for(uint32 i=0; i<numberOfObjects; i++)
@@ -279,6 +282,7 @@ void OPDumpObjectList(void)
        WriteLog("\n");
 }
 
+
 //
 // Object Processor memory access
 // Memory range: F00010 - F00027
@@ -319,12 +323,14 @@ WriteLog("OP: Setting hi list pointer: %04X\n", data);//*/
 }
 #endif
 
+
 uint32 OPGetListPointer(void)
 {
        // Note: This register is LO / HI WORD, hence the funky look of this...
        return GET16(tomRam8, 0x20) | (GET16(tomRam8, 0x22) << 16);
 }
 
+
 // This is WRONG, since the OBF is only 16 bits wide!!! [FIXED]
 
 uint32 OPGetStatusRegister(void)
@@ -332,6 +338,7 @@ uint32 OPGetStatusRegister(void)
        return GET16(tomRam8, 0x26);
 }
 
+
 // This is WRONG, since the OBF is only 16 bits wide!!! [FIXED]
 
 void OPSetStatusRegister(uint32 data)
@@ -340,6 +347,7 @@ void OPSetStatusRegister(uint32 data)
        tomRam8[0x27] |= (data & 0xFE);
 }
 
+
 void OPSetCurrentObject(uint64 object)
 {
 //Not sure this is right... Wouldn't it just be stored 64 bit BE?
@@ -365,12 +373,14 @@ void OPSetCurrentObject(uint64 object)
        tomRam8[0x10] = object & 0xFF;
 }
 
+
 uint64 OPLoadPhrase(uint32 offset)
 {
        offset &= ~0x07;                                                // 8 byte alignment
        return ((uint64)JaguarReadLong(offset, OP) << 32) | (uint64)JaguarReadLong(offset+4, OP);
 }
 
+
 void OPStorePhrase(uint32 offset, uint64 p)
 {
        offset &= ~0x07;                                                // 8 byte alignment
@@ -378,6 +388,7 @@ void OPStorePhrase(uint32 offset, uint64 p)
        JaguarWriteLong(offset + 4, p & 0xFFFFFFFF, OP);
 }
 
+
 //
 // Debugging routines
 //
@@ -392,12 +403,14 @@ void DumpScaledObject(uint64 p0, uint64 p1, uint64 p2)
        WriteLog("    [hsc: %02X, vsc: %02X, rem: %02X]\n", hscale, vscale, remainder);
 }
 
+
 void DumpFixedObject(uint64 p0, uint64 p1)
 {
        WriteLog("          %08X %08X\n", (uint32)(p1>>32), (uint32)(p1&0xFFFFFFFF));
        DumpBitmapCore(p0, p1);
 }
 
+
 void DumpBitmapCore(uint64 p0, uint64 p1)
 {
        uint32 bdMultiplier[8] = { 64, 32, 16, 8, 4, 2, 1, 1 };
@@ -423,6 +436,7 @@ void DumpBitmapCore(uint64 p0, uint64 p1)
                (flags&OPFLAG_RELEASE ? "RELEASE" : ""), idx, pitch);
 }
 
+
 //
 // Object Processor main routine
 //
@@ -616,8 +630,17 @@ if (!inhibit)      // For OP testing only!
 /*     if (op_pointer > ((p0 & 0x000007FFFF000000LL) >> 21))
                return;*/
 
-                       op_pointer = (p0 & 0x000007FFFF000000LL) >> 21;
+// NOTE: The link address only replaces bits 3-21 in the OLP, and this replaces
+//       EVERYTHING. !!! FIX !!! [DONE]
+#warning "!!! Link address is not linked properly for all object types !!!"
+#warning "!!! Only BITMAP is properly handled !!!"
+                       op_pointer &= 0xFFC00007;
+                       op_pointer |= (p0 & 0x000007FFFF000000LL) >> 21;
 //WriteLog("New OP: %08X\n", op_pointer);
+//kludge: Seems that memory access is mirrored in the first 8MB of memory...
+if (op_pointer > 0x1FFFFF && op_pointer < 0x800000)
+       op_pointer &= 0xFF1FFFFF;       // Knock out bits 21-23
+
                        break;
                }
                case OBJECT_TYPE_SCALE:
@@ -771,6 +794,7 @@ OP: Scaled bitmap 4x? 4bpp at 34,? hscale=80 fpix=0 data=000756E8 pitch 1 hflipp
                        uint16 ypos = (p0 >> 3) & 0x7FF;
 // NOTE: The JTRM sez there are only 2 bits used for the CC, but lists *five*
 //       conditions! Need at least one more bit for that! :-P
+// Also, the ASIC nets imply that it uses bits 14-16 (height in BM & SBM objects)
 #warning "!!! Possibly bad CC handling in OP (missing 1 bit) !!!"
                        uint8  cc   = (p0 >> 14) & 0x03;
                        uint32 link = (p0 >> 21) & 0x3FFFF8;
@@ -836,7 +860,7 @@ OP: Scaled bitmap 4x? 4bpp at 34,? hscale=80 fpix=0 data=000756E8 pitch 1 hflipp
 //                     break;
                }
                default:
-                       WriteLog("op: unknown object type %i\n", ((uint8)p0 & 0x07));
+//                     WriteLog("op: unknown object type %i\n", ((uint8)p0 & 0x07));
                        return;
                }
 
@@ -851,6 +875,7 @@ OP: Scaled bitmap 4x? 4bpp at 34,? hscale=80 fpix=0 data=000756E8 pitch 1 hflipp
        }
 }
 
+
 //
 // Store fixed size bitmap in line buffer
 //
@@ -894,6 +919,13 @@ void OPProcessFixedBitmap(uint64 p0, uint64 p1, bool render)
 // Is it OK to have a 0 for the data width??? (i.e., undocumented?)
 // Seems to be... Seems that dwidth *can* be zero (i.e., reuse same line) as well.
 // Pitch == 0 is OK too...
+
+//kludge: Seems that the OP treats iwidth == 0 as iwidth == 1... Need to investigate
+//        on real hardware...
+#warning "!!! Need to investigate iwidth == 0 behavior on real hardware !!!"
+if (iwidth == 0)
+       iwidth = 1;
+
 //     if (!render || op_pointer == 0 || ptr == 0 || pitch == 0)
 //I'm not convinced that we need to concern ourselves with data & op_pointer here either!
        if (!render || iwidth == 0)
@@ -1308,6 +1340,7 @@ if (firstPix)
        }
 }
 
+
 //
 // Store scaled bitmap in line buffer
 //