X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fop.cpp;h=ba8a1b4312d17d3f94992eb28cca908550786e97;hb=ec46f1b3c40cf464d833e360346b4f6f8379b9ae;hp=73fc330010dced9a3a83a71f345d33dbbc54369c;hpb=8edf7ac06469707cc221b2cdaa8bea0ed4e2f898;p=virtualjaguar diff --git a/src/op.cpp b/src/op.cpp index 73fc330..ba8a1b4 100644 --- a/src/op.cpp +++ b/src/op.cpp @@ -51,8 +51,11 @@ void OPProcessFixedBitmap(uint64 p0, uint64 p1, bool render); void OPProcessScaledBitmap(uint64 p0, uint64 p1, uint64 p2, bool render); +void OPDiscoverObjects(uint32 address); +void OPDumpObjectList(void); void DumpScaledObject(uint64 p0, uint64 p1, uint64 p2); void DumpFixedObject(uint64 p0, uint64 p1); +void DumpBitmapCore(uint64 p0, uint64 p1); uint64 OPLoadPhrase(uint32 offset); // Local global variables @@ -131,20 +134,33 @@ void OPReset(void) objectp_running = 0; } +static const char * opType[8] = +{ "(BITMAP)", "(SCALED BITMAP)", "(GPU INT)", "(BRANCH)", "(STOP)", "???", "???", "???" }; +static const char * ccType[8] = + { "\"==\"", "\"<\"", "\">\"", "(opflag set)", "(second half line)", "?", "?", "?" }; +static uint32 object[8192]; +static uint32 numberOfObjects; +//static uint32 objectLink[8192]; +//static uint32 numberOfLinks; + void OPDone(void) { - const char * opType[8] = - { "(BITMAP)", "(SCALED BITMAP)", "(GPU INT)", "(BRANCH)", "(STOP)", "???", "???", "???" }; - const char * ccType[8] = - { "\"==\"", "\"<\"", "\">\"", "(opflag set)", "(second half line)", "?", "?", "?" }; +//#warning "!!! Fix OL dump so that it follows links !!!" +// const char * opType[8] = +// { "(BITMAP)", "(SCALED BITMAP)", "(GPU INT)", "(BRANCH)", "(STOP)", "???", "???", "???" }; +// const char * ccType[8] = +// { "\"==\"", "\"<\"", "\">\"", "(opflag set)", "(second half line)", "?", "?", "?" }; uint32 olp = OPGetListPointer(); - WriteLog("OP: OLP = %08X\n", olp); + WriteLog("\nOP: OLP = $%08X\n", olp); WriteLog("OP: Phrase dump\n ----------\n"); + +#if 0 for(uint32 i=0; i<0x100; i+=8) { uint32 hi = JaguarReadLong(olp + i, OP), lo = JaguarReadLong(olp + i + 4, OP); WriteLog("\t%08X: %08X %08X %s", olp + i, hi, lo, opType[lo & 0x07]); + if ((lo & 0x07) == 3) { uint16 ypos = (lo >> 3) & 0x7FF; @@ -152,16 +168,115 @@ void OPDone(void) uint32 link = ((hi << 11) | (lo >> 21)) & 0x3FFFF8; WriteLog(" YPOS=%u, CC=%s, link=%08X", ypos, ccType[cc], link); } + WriteLog("\n"); + if ((lo & 0x07) == 0) DumpFixedObject(OPLoadPhrase(olp+i), OPLoadPhrase(olp+i+8)); + if ((lo & 0x07) == 1) DumpScaledObject(OPLoadPhrase(olp+i), OPLoadPhrase(olp+i+8), OPLoadPhrase(olp+i+16)); } + WriteLog("\n"); +#else + numberOfObjects = 0; + OPDiscoverObjects(olp); + OPDumpObjectList(); +#endif +} + +void OPDiscoverObjects(uint32 address) +{ + // Check to see if we've already seen this object + for(uint32 i=0; i> 21)) & 0x3FFFF8; + + if (objectType == 3) + { + uint16 ypos = (lo >> 3) & 0x7FF; + uint8 cc = (lo >> 14) & 0x07; // Proper # of bits == 3 + + // Recursion needed to follow all links! + OPDiscoverObjects(address + 8); + } + + if (address == link) // Ruh roh... + { + // Runaway recursive link is bad! + return; + } + + 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> 21)) & 0x3FFFF8; + WriteLog("%08X: %08X %08X %s", address, hi, lo, opType[objectType]); -// memory_free(op_blend_y); -// memory_free(op_blend_cr); + if (objectType == 3) + { + uint16 ypos = (lo >> 3) & 0x7FF; + uint8 cc = (lo >> 14) & 0x07; // Proper # of bits == 3 + WriteLog(" YPOS=%u, CC=%s, link=$%08X", ypos, ccType[cc], link); + } + + WriteLog("\n"); + + if (objectType == 0) + DumpFixedObject(OPLoadPhrase(address + 0), OPLoadPhrase(address + 8)); + + if (objectType == 1) + DumpScaledObject(OPLoadPhrase(address + 0), OPLoadPhrase(address + 8), + OPLoadPhrase(address + 16)); + + if (address == link) // Ruh roh... + { + // Runaway recursive link is bad! + WriteLog("***** SELF REFERENTIAL LINK *****\n\n"); + } + } + + WriteLog("\n"); } // @@ -268,25 +383,9 @@ void OPStorePhrase(uint32 offset, uint64 p) // void DumpScaledObject(uint64 p0, uint64 p1, uint64 p2) { - WriteLog(" (SCALED BITMAP)"); - WriteLog(" %08X --> phrase %08X %08X\n", op_pointer, (uint32)(p1>>32), (uint32)(p1&0xFFFFFFFF)); - WriteLog(" %08X --> phrase %08X %08X ", op_pointer+8, (uint32)(p2>>32), (uint32)(p2&0xFFFFFFFF)); - uint8 bitdepth = (p1 >> 12) & 0x07; -//WAS: int16 ypos = ((p0 >> 3) & 0x3FF); // ??? What if not interlaced (/2)? - int16 ypos = ((p0 >> 3) & 0x7FF); // ??? What if not interlaced (/2)? - int32 xpos = p1 & 0xFFF; - xpos = (xpos & 0x800 ? xpos | 0xFFFFF000 : xpos); - uint32 iwidth = ((p1 >> 28) & 0x3FF); - uint32 dwidth = ((p1 >> 18) & 0x3FF); // Unsigned! - uint16 height = ((p0 >> 14) & 0x3FF); - uint32 link = ((p0 >> 24) & 0x7FFFF) << 3; - uint32 ptr = ((p0 >> 43) & 0x1FFFFF) << 3; - uint32 firstPix = (p1 >> 49) & 0x3F; - uint8 flags = (p1 >> 45) & 0x0F; - uint8 idx = (p1 >> 38) & 0x7F; - uint32 pitch = (p1 >> 15) & 0x07; - WriteLog("\n [%u (%u) x %u @ (%i, %u) (%u bpp), l: %08X, p: %08X fp: %02X, fl:%s%s%s%s, idx:%02X, pt:%02X]\n", - iwidth, dwidth, height, xpos, ypos, op_bitmap_bit_depth[bitdepth], link, ptr, firstPix, (flags&OPFLAG_REFLECT ? "REFLECT " : ""), (flags&OPFLAG_RMW ? "RMW " : ""), (flags&OPFLAG_TRANS ? "TRANS " : ""), (flags&OPFLAG_RELEASE ? "RELEASE" : ""), idx, pitch); + WriteLog(" %08X %08X\n", (uint32)(p1>>32), (uint32)(p1&0xFFFFFFFF)); + WriteLog(" %08X %08X\n", (uint32)(p2>>32), (uint32)(p2&0xFFFFFFFF)); + DumpBitmapCore(p0, p1); uint32 hscale = p2 & 0xFF; uint32 vscale = (p2 >> 8) & 0xFF; uint32 remainder = (p2 >> 16) & 0xFF; @@ -295,13 +394,18 @@ void DumpScaledObject(uint64 p0, uint64 p1, uint64 p2) void DumpFixedObject(uint64 p0, uint64 p1) { - WriteLog(" (BITMAP)"); - WriteLog(" %08X --> phrase %08X %08X\n", op_pointer, (uint32)(p1>>32), (uint32)(p1&0xFFFFFFFF)); + 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 }; uint8 bitdepth = (p1 >> 12) & 0x07; //WAS: int16 ypos = ((p0 >> 3) & 0x3FF); // ??? What if not interlaced (/2)? int16 ypos = ((p0 >> 3) & 0x7FF); // ??? What if not interlaced (/2)? int32 xpos = p1 & 0xFFF; - xpos = (xpos & 0x800 ? xpos | 0xFFFFF000 : xpos); + xpos = (xpos & 0x800 ? xpos | 0xFFFFF000 : xpos); // Sign extend that mutha! uint32 iwidth = ((p1 >> 28) & 0x3FF); uint32 dwidth = ((p1 >> 18) & 0x3FF); // Unsigned! uint16 height = ((p0 >> 14) & 0x3FF); @@ -311,16 +415,24 @@ void DumpFixedObject(uint64 p0, uint64 p1) uint8 flags = (p1 >> 45) & 0x0F; uint8 idx = (p1 >> 38) & 0x7F; uint32 pitch = (p1 >> 15) & 0x07; - WriteLog(" [%u (%u) x %u @ (%i, %u) (%u bpp), l: %08X, p: %08X fp: %02X, fl:%s%s%s%s, idx:%02X, pt:%02X]\n", - iwidth, dwidth, height, xpos, ypos, op_bitmap_bit_depth[bitdepth], link, ptr, firstPix, (flags&OPFLAG_REFLECT ? "REFLECT " : ""), (flags&OPFLAG_RMW ? "RMW " : ""), (flags&OPFLAG_TRANS ? "TRANS " : ""), (flags&OPFLAG_RELEASE ? "RELEASE" : ""), idx, pitch); + WriteLog(" [%u x %u @ (%i, %u) (iw:%u, dw:%u) (%u bpp), l:%08X, p:%08X fp:%02X, fl:%s%s%s%s, idx:%02X, pt:%02X]\n", + iwidth * bdMultiplier[bitdepth], + height, xpos, ypos, iwidth, dwidth, op_bitmap_bit_depth[bitdepth], link, + ptr, firstPix, (flags&OPFLAG_REFLECT ? "REFLECT " : ""), + (flags&OPFLAG_RMW ? "RMW " : ""), (flags&OPFLAG_TRANS ? "TRANS " : ""), + (flags&OPFLAG_RELEASE ? "RELEASE" : ""), idx, pitch); } // // Object Processor main routine // #warning "Need to fix this so that when an GPU object IRQ happens, we can pick up OP processing where we left off. !!! FIX !!!" -void OPProcessList(int scanline, bool render) +void OPProcessList(int halfline, bool render) { +#warning "!!! NEED TO HANDLE MULTIPLE FIELDS PROPERLY !!! +// We ignore them, for now; not good + halfline &= 0x7FF; + extern int op_start_log; // char * condition_to_str[8] = // { "==", "<", ">", "(opflag set)", "(second half line)", "?", "?", "?" }; @@ -329,7 +441,7 @@ extern int op_start_log; // objectp_stop_reading_list = false; -//WriteLog("OP: Processing line #%u (OLP=%08X)...\n", scanline, op_pointer); +//WriteLog("OP: Processing line #%u (OLP=%08X)...\n", halfline, op_pointer); //op_done(); // *** BEGIN OP PROCESSOR TESTING ONLY *** @@ -342,7 +454,7 @@ int bitmapCounter = 0; uint32 opCyclesToRun = 30000; // This is a pulled-out-of-the-air value (will need to be fixed, obviously!) -// if (op_pointer) WriteLog(" new op list at 0x%.8x scanline %i\n",op_pointer,scanline); +// if (op_pointer) WriteLog(" new op list at 0x%.8x halfline %i\n",op_pointer,halfline); while (op_pointer) { // *** BEGIN OP PROCESSOR TESTING ONLY *** @@ -355,14 +467,14 @@ else // return; uint64 p0 = OPLoadPhrase(op_pointer); -//WriteLog("\t%08X type %i\n", op_pointer, (uint8)p0 & 0x07); op_pointer += 8; +//WriteLog("\t%08X type %i\n", op_pointer, (uint8)p0 & 0x07); #if 1 -if (scanline == TOMGetVDB() && op_start_log) -//if (scanline == 215 && op_start_log) -//if (scanline == 28 && op_start_log) -//if (scanline == 0) +if (halfline == TOMGetVDB() && op_start_log) +//if (halfline == 215 && op_start_log) +//if (halfline == 28 && op_start_log) +//if (halfline == 0) { WriteLog("%08X --> phrase %08X %08X", op_pointer - 8, (int)(p0>>32), (int)(p0&0xFFFFFFFF)); if ((p0 & 0x07) == OBJECT_TYPE_BITMAP) @@ -463,13 +575,13 @@ if (inhibit && op_start_log) bitmapCounter++; if (!inhibit) // For OP testing only! // *** END OP PROCESSOR TESTING ONLY *** - if (scanline >= ypos && height > 0) + if (halfline >= ypos && height > 0) { uint64 p1 = OPLoadPhrase(op_pointer); op_pointer += 8; -//WriteLog("OP: Writing scanline %d with ypos == %d...\n", scanline, ypos); +//WriteLog("OP: Writing halfline %d with ypos == %d...\n", halfline, ypos); //WriteLog("--> Writing %u BPP bitmap...\n", op_bitmap_bit_depth[(p1 >> 12) & 0x07]); -// OPProcessFixedBitmap(scanline, p0, p1, render); +// OPProcessFixedBitmap(halfline, p0, p1, render); OPProcessFixedBitmap(p0, p1, render); // OP write-backs @@ -518,19 +630,19 @@ if (!inhibit) // For OP testing only! // *** BEGIN OP PROCESSOR TESTING ONLY *** if (inhibit && op_start_log) { - WriteLog("!!! ^^^ This object is INHIBITED! ^^^ !!! (scanline=%u, ypos=%u, height=%u)\n", scanline, ypos, height); + WriteLog("!!! ^^^ This object is INHIBITED! ^^^ !!! (halfline=%u, ypos=%u, height=%u)\n", halfline, ypos, height); DumpScaledObject(p0, OPLoadPhrase(op_pointer), OPLoadPhrase(op_pointer+8)); } bitmapCounter++; if (!inhibit) // For OP testing only! // *** END OP PROCESSOR TESTING ONLY *** - if (scanline >= ypos && height > 0) + if (halfline >= ypos && height > 0) { uint64 p1 = OPLoadPhrase(op_pointer); op_pointer += 8; uint64 p2 = OPLoadPhrase(op_pointer); op_pointer += 8; -//WriteLog("OP: %08X (%d) %08X%08X %08X%08X %08X%08X\n", oldOPP, scanline, (uint32)(p0>>32), (uint32)(p0&0xFFFFFFFF), (uint32)(p1>>32), (uint32)(p1&0xFFFFFFFF), (uint32)(p2>>32), (uint32)(p2&0xFFFFFFFF)); +//WriteLog("OP: %08X (%d) %08X%08X %08X%08X %08X%08X\n", oldOPP, halfline, (uint32)(p0>>32), (uint32)(p0&0xFFFFFFFF), (uint32)(p1>>32), (uint32)(p1&0xFFFFFFFF), (uint32)(p2>>32), (uint32)(p2&0xFFFFFFFF)); OPProcessScaledBitmap(p0, p1, p2, render); // OP write-backs @@ -584,7 +696,7 @@ OP: Scaled bitmap 4x? 4bpp at 34,? hscale=80 fpix=0 data=000756E8 pitch 1 hflipp //Here's another problem: // [hsc: 20, vsc: 20, rem: 00] // Since we're not checking for $E0 (but that's what we get from the above), we end -// up repeating this scanline unnecessarily... !!! FIX !!! [DONE, but... still not quite +// up repeating this halfline unnecessarily... !!! FIX !!! [DONE, but... still not quite // right. Either that, or the Accolade team that wrote Bubsy screwed up royal.] //Also note: $E0 = 7.0 which IS a legal vscale value... @@ -650,18 +762,21 @@ OP: Scaled bitmap 4x? 4bpp at 34,? hscale=80 fpix=0 data=000756E8 pitch 1 hflipp //Do something like: //OPSuspendedByGPU = true; //Dunno if the OP keeps processing from where it was interrupted, or if it just continues -//on the next scanline... +//on the next halfline... // --> It continues from where it was interrupted! !!! FIX !!! break; } case OBJECT_TYPE_BRANCH: { 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 +#warning "!!! Possibly bad CC handling in OP (missing 1 bit) !!!" uint8 cc = (p0 >> 14) & 0x03; uint32 link = (p0 >> 21) & 0x3FFFF8; // if ((ypos!=507)&&(ypos!=25)) -// WriteLog("\t%i%s%i link=0x%.8x\n",scanline,condition_to_str[cc],ypos>>1,link); +// WriteLog("\t%i%s%i link=0x%.8x\n",halfline,condition_to_str[cc],ypos>>1,link); switch (cc) { case CONDITION_EQUAL: @@ -692,6 +807,7 @@ OP: Scaled bitmap 4x? 4bpp at 34,? hscale=80 fpix=0 data=000756E8 pitch 1 hflipp exit(0); break; default: + // Basically, if you do this, the OP does nothing. :-) WriteLog("OP: Unimplemented branch condition %i\n", cc); } break; @@ -729,6 +845,7 @@ OP: Scaled bitmap 4x? 4bpp at 34,? hscale=80 fpix=0 data=000756E8 pitch 1 hflipp // and bail out/reenter to properly simulate an overloaded OP... !!! FIX !!! #warning "Better would be to count how many actual cycles it used and bail out/reenter to properly simulate an overloaded OP... !!! FIX !!!" opCyclesToRun--; + if (!opCyclesToRun) return; }