#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
OPReset();
}
+
//
// Object Processor reset
//
objectp_running = 0;
}
+
static const char * opType[8] =
{ "(BITMAP)", "(SCALED BITMAP)", "(GPU INT)", "(BRANCH)", "(STOP)", "???", "???", "???" };
static const char * ccType[8] =
//static uint32 objectLink[8192];
//static uint32 numberOfLinks;
+
void OPDone(void)
{
//#warning "!!! Fix OL dump so that it follows links !!!"
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;
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++)
WriteLog("\n");
}
+
//
// Object Processor memory access
// Memory range: F00010 - F00027
}
#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)
return GET16(tomRam8, 0x26);
}
+
// This is WRONG, since the OBF is only 16 bits wide!!! [FIXED]
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?
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
JaguarWriteLong(offset + 4, p & 0xFFFFFFFF, OP);
}
+
//
// Debugging routines
//
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 };
(flags&OPFLAG_RELEASE ? "RELEASE" : ""), idx, pitch);
}
+
//
// Object Processor main routine
//
/* 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:
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;
// break;
}
default:
- WriteLog("op: unknown object type %i\n", ((uint8)p0 & 0x07));
+// WriteLog("op: unknown object type %i\n", ((uint8)p0 & 0x07));
return;
}
}
}
+
//
// Store fixed size bitmap in line buffer
//
// 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)
}
}
+
//
// Store scaled bitmap in line buffer
//