// Seems alignment in loads & stores was off...
#define GPU_CORRECT_ALIGNMENT
-//#define GPU_CORRECT_ALIGNMENT_STORE
//#define GPU_DEBUG
// For GPU dissasembly...
if (doGPUDis)
WriteLog("%06X: STORE R%02u, (R14+$%02X) [NCZ:%u%u%u, R%02u=%08X, R14+$%02X=%08X]\n", gpu_pc-2, IMM_2, gpu_convert_zero[IMM_1] << 2, gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_2, RN, gpu_convert_zero[IMM_1] << 2, gpu_reg[14]+(gpu_convert_zero[IMM_1] << 2));
#endif
-#ifdef GPU_CORRECT_ALIGNMENT_STORE
- GPUWriteLong((gpu_reg[14] & 0xFFFFFFFC) + (gpu_convert_zero[IMM_1] << 2), RN, GPU);
+#ifdef GPU_CORRECT_ALIGNMENT
+ uint32 address = gpu_reg[14] + (gpu_convert_zero[IMM_1] << 2);
+
+ if (address >= 0xF03000 && address <= 0xF03FFF)
+ GPUWriteLong(address & 0xFFFFFFFC, RN, GPU);
+ else
+ GPUWriteLong(address, RN, GPU);
#else
GPUWriteLong(gpu_reg[14] + (gpu_convert_zero[IMM_1] << 2), RN, GPU);
#endif
if (doGPUDis)
WriteLog("%06X: STORE R%02u, (R15+$%02X) [NCZ:%u%u%u, R%02u=%08X, R15+$%02X=%08X]\n", gpu_pc-2, IMM_2, gpu_convert_zero[IMM_1] << 2, gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_2, RN, gpu_convert_zero[IMM_1] << 2, gpu_reg[15]+(gpu_convert_zero[IMM_1] << 2));
#endif
-#ifdef GPU_CORRECT_ALIGNMENT_STORE
- GPUWriteLong((gpu_reg[15] & 0xFFFFFFFC) + (gpu_convert_zero[IMM_1] << 2), RN, GPU);
+#ifdef GPU_CORRECT_ALIGNMENT
+ uint32 address = gpu_reg[15] + (gpu_convert_zero[IMM_1] << 2);
+
+ if (address >= 0xF03000 && address <= 0xF03FFF)
+ GPUWriteLong(address & 0xFFFFFFFC, RN, GPU);
+ else
+ GPUWriteLong(address, RN, GPU);
#else
GPUWriteLong(gpu_reg[15] + (gpu_convert_zero[IMM_1] << 2), RN, GPU);
#endif
WriteLog("%06X: LOAD (R14+R%02u), R%02u [NCZ:%u%u%u, R14+R%02u=%08X, R%02u=%08X] -> ", gpu_pc-2, IMM_1, IMM_2, gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_1, RM+gpu_reg[14], IMM_2, RN);
#endif
#ifdef GPU_CORRECT_ALIGNMENT
- RN = GPUReadLong((gpu_reg[14] + RM) & 0xFFFFFFFC, GPU);
+ uint32 address = gpu_reg[14] + RM;
+
+ if (address >= 0xF03000 && address <= 0xF03FFF)
+ RN = GPUReadLong(address & 0xFFFFFFFC, GPU);
+ else
+ RN = GPUReadLong(address, GPU);
#else
RN = GPUReadLong(gpu_reg[14] + RM, GPU);
#endif
WriteLog("%06X: LOAD (R15+R%02u), R%02u [NCZ:%u%u%u, R15+R%02u=%08X, R%02u=%08X] -> ", gpu_pc-2, IMM_1, IMM_2, gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_1, RM+gpu_reg[15], IMM_2, RN);
#endif
#ifdef GPU_CORRECT_ALIGNMENT
- RN = GPUReadLong((gpu_reg[15] + RM) & 0xFFFFFFFC, GPU);
+ uint32 address = gpu_reg[15] + RM;
+
+ if (address >= 0xF03000 && address <= 0xF03FFF)
+ RN = GPUReadLong(address & 0xFFFFFFFC, GPU);
+ else
+ RN = GPUReadLong(address, GPU);
#else
RN = GPUReadLong(gpu_reg[15] + RM, GPU);
#endif
if (doGPUDis)
WriteLog("%06X: STORE R%02u, (R14+R%02u) [NCZ:%u%u%u, R%02u=%08X, R14+R%02u=%08X]\n", gpu_pc-2, IMM_2, IMM_1, gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_2, RN, IMM_1, RM+gpu_reg[14]);
#endif
-#ifdef GPU_CORRECT_ALIGNMENT_STORE
- GPUWriteLong((gpu_reg[14] + RM) & 0xFFFFFFFC, RN, GPU);
+#ifdef GPU_CORRECT_ALIGNMENT
+ uint32 address = gpu_reg[14] + RM;
+
+ if (address >= 0xF03000 && address <= 0xF03FFF)
+ GPUWriteLong(address & 0xFFFFFFFC, RN, GPU);
+ else
+ GPUWriteLong(address, RN, GPU);
#else
GPUWriteLong(gpu_reg[14] + RM, RN, GPU);
#endif
WriteLog("%06X: STORE R%02u, (R15+R%02u) [NCZ:%u%u%u, R%02u=%08X, R15+R%02u=%08X]\n", gpu_pc-2, IMM_2, IMM_1, gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_2, RN, IMM_1, RM+gpu_reg[15]);
#endif
#ifdef GPU_CORRECT_ALIGNMENT_STORE
- GPUWriteLong((gpu_reg[15] + RM) & 0xFFFFFFFC, RN, GPU);
+ uint32 address = gpu_reg[15] + RM;
+
+ if (address >= 0xF03000 && address <= 0xF03FFF)
+ GPUWriteLong(address & 0xFFFFFFFC, RN, GPU);
+ else
+ GPUWriteLong(address, RN, GPU);
#else
GPUWriteLong(gpu_reg[15] + RM, RN, GPU);
#endif
if (doGPUDis)
WriteLog("%06X: STOREW R%02u, (R%02u) [NCZ:%u%u%u, R%02u=%08X, R%02u=%08X]\n", gpu_pc-2, IMM_2, IMM_1, gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_2, RN, IMM_1, RM);
#endif
-#ifdef GPU_CORRECT_ALIGNMENT_STORE
+#ifdef GPU_CORRECT_ALIGNMENT
if ((RM >= 0xF03000) && (RM <= 0xF03FFF))
GPUWriteLong(RM & 0xFFFFFFFE, RN & 0xFFFF, GPU);
else
- JaguarWriteWord(RM & 0xFFFFFFFE, RN, GPU);
+ JaguarWriteWord(RM, RN, GPU);
#else
if ((RM >= 0xF03000) && (RM <= 0xF03FFF))
GPUWriteLong(RM, RN & 0xFFFF, GPU);
if (doGPUDis)
WriteLog("%06X: STORE R%02u, (R%02u) [NCZ:%u%u%u, R%02u=%08X, R%02u=%08X]\n", gpu_pc-2, IMM_2, IMM_1, gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_2, RN, IMM_1, RM);
#endif
-#ifdef GPU_CORRECT_ALIGNMENT_STORE
- GPUWriteLong(RM & 0xFFFFFFFC, RN, GPU);
+#ifdef GPU_CORRECT_ALIGNMENT
+ if ((RM >= 0xF03000) && (RM <= 0xF03FFF))
+ GPUWriteLong(RM & 0xFFFFFFFC, RN, GPU);
+ else
+ GPUWriteLong(RM, RN, GPU);
#else
GPUWriteLong(RM, RN, GPU);
#endif
static void gpu_opcode_storep(void)
{
-#ifdef GPU_CORRECT_ALIGNMENT_STORE
- GPUWriteLong((RM & 0xFFFFFFF8) + 0, gpu_hidata, GPU);
- GPUWriteLong((RM & 0xFFFFFFF8) + 4, RN, GPU);
+#ifdef GPU_CORRECT_ALIGNMENT
+ if ((RM >= 0xF03000) && (RM <= 0xF03FFF))
+ {
+ GPUWriteLong((RM & 0xFFFFFFF8) + 0, gpu_hidata, GPU);
+ GPUWriteLong((RM & 0xFFFFFFF8) + 4, RN, GPU);
+ }
+ else
+ {
+ GPUWriteLong(RM + 0, gpu_hidata, GPU);
+ GPUWriteLong(RM + 4, RN, GPU);
+ }
#else
GPUWriteLong(RM + 0, gpu_hidata, GPU);
GPUWriteLong(RM + 4, RN, GPU);
if ((RM >= 0xF03000) && (RM <= 0xF03FFF))
RN = GPUReadLong(RM & 0xFFFFFFFE, GPU) & 0xFFFF;
else
- RN = JaguarReadWord(RM & 0xFFFFFFFE, GPU);
+ RN = JaguarReadWord(RM, GPU);
#else
if ((RM >= 0xF03000) && (RM <= 0xF03FFF))
RN = GPUReadLong(RM, GPU) & 0xFFFF;
// According to the docs, & "Do The Same", this address is long aligned...
// So let's try it:
// And it works!!! Need to fix all instances...
+// Also, Power Drive Rally seems to contradict the idea that only LOADs in
+// the $F03000-$F03FFF range are aligned...
+#warning "!!! Alignment issues, need to find definitive final word on this !!!"
static void gpu_opcode_load(void)
{
#ifdef GPU_DIS_LOAD
WriteLog("%06X: LOAD (R%02u), R%02u [NCZ:%u%u%u, R%02u=%08X, R%02u=%08X] -> ", gpu_pc-2, IMM_1, IMM_2, gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_1, RM, IMM_2, RN);
#endif
#ifdef GPU_CORRECT_ALIGNMENT
- RN = GPUReadLong(RM & 0xFFFFFFFC, GPU);
+// if ((RM >= 0xF03000) && (RM <= 0xF03FFF))
+ RN = GPUReadLong(RM & 0xFFFFFFFC, GPU);
+// else
+// RN = GPUReadLong(RM, GPU);
#else
RN = GPUReadLong(RM, GPU);
#endif
static void gpu_opcode_loadp(void)
{
#ifdef GPU_CORRECT_ALIGNMENT
- gpu_hidata = GPUReadLong((RM & 0xFFFFFFF8) + 0, GPU);
- RN = GPUReadLong((RM & 0xFFFFFFF8) + 4, GPU);
+ if ((RM >= 0xF03000) && (RM <= 0xF03FFF))
+ {
+ gpu_hidata = GPUReadLong((RM & 0xFFFFFFF8) + 0, GPU);
+ RN = GPUReadLong((RM & 0xFFFFFFF8) + 4, GPU);
+ }
+ else
+ {
+ gpu_hidata = GPUReadLong(RM + 0, GPU);
+ RN = GPUReadLong(RM + 4, GPU);
+ }
#else
gpu_hidata = GPUReadLong(RM + 0, GPU);
RN = GPUReadLong(RM + 4, GPU);
WriteLog("%06X: LOAD (R14+$%02X), R%02u [NCZ:%u%u%u, R14+$%02X=%08X, R%02u=%08X] -> ", gpu_pc-2, gpu_convert_zero[IMM_1] << 2, IMM_2, gpu_flag_n, gpu_flag_c, gpu_flag_z, gpu_convert_zero[IMM_1] << 2, gpu_reg[14]+(gpu_convert_zero[IMM_1] << 2), IMM_2, RN);
#endif
#ifdef GPU_CORRECT_ALIGNMENT
- RN = GPUReadLong((gpu_reg[14] & 0xFFFFFFFC) + (gpu_convert_zero[IMM_1] << 2), GPU);
+ uint32 address = gpu_reg[14] + (gpu_convert_zero[IMM_1] << 2);
+
+ if ((RM >= 0xF03000) && (RM <= 0xF03FFF))
+ RN = GPUReadLong(address & 0xFFFFFFFC, GPU);
+ else
+ RN = GPUReadLong(address, GPU);
#else
RN = GPUReadLong(gpu_reg[14] + (gpu_convert_zero[IMM_1] << 2), GPU);
#endif
WriteLog("%06X: LOAD (R15+$%02X), R%02u [NCZ:%u%u%u, R15+$%02X=%08X, R%02u=%08X] -> ", gpu_pc-2, gpu_convert_zero[IMM_1] << 2, IMM_2, gpu_flag_n, gpu_flag_c, gpu_flag_z, gpu_convert_zero[IMM_1] << 2, gpu_reg[15]+(gpu_convert_zero[IMM_1] << 2), IMM_2, RN);
#endif
#ifdef GPU_CORRECT_ALIGNMENT
- RN = GPUReadLong((gpu_reg[15] & 0xFFFFFFFC) + (gpu_convert_zero[IMM_1] << 2), GPU);
+ uint32 address = gpu_reg[15] + (gpu_convert_zero[IMM_1] << 2);
+
+ if ((RM >= 0xF03000) && (RM <= 0xF03FFF))
+ RN = GPUReadLong(address & 0xFFFFFFFC, GPU);
+ else
+ RN = GPUReadLong(address, GPU);
#else
RN = GPUReadLong(gpu_reg[15] + (gpu_convert_zero[IMM_1] << 2), GPU);
#endif
// JLH 01/16/2010 Created this log ;-)
// JLH 07/11/2011 Instead of dumping out on max log file size being reached, we
// now just silently ignore any more output. 10 megs ought to be
-// enough for anybody. ;-)
+// enough for anybody. ;-) Except when it isn't. :-P
//
#include "log.h"
void OPProcessFixedBitmap(uint64 p0, uint64 p1, bool render);
void OPProcessScaledBitmap(uint64 p0, uint64 p1, uint64 p2, bool render);
+void OPDumpObjectList(uint32 address);
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
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 objectLink[8192];
+static uint32 numberOfLinks;
+
void OPDone(void)
{
-#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)", "?", "?", "?" };
+//#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;
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
+ numberOfLinks = 0;
+
+ OPDumpObjectList(olp);
+#endif
+}
+
+
+// To do this properly, we have to use recursion...
+void OPDumpObjectList(uint32 address)
+{
+ // Sanity checking: If we've already visited this link, bail out!
+ for(uint32 i=0; i<numberOfLinks; i++)
+ {
+ if (address == objectLink[i])
+ return;
+ }
+
+ objectLink[numberOfLinks++] = address;
+ uint8 objectType = 0;
+
+ do
+ {
+ uint32 hi = JaguarReadLong(address + 0, OP);
+ uint32 lo = JaguarReadLong(address + 4, OP);
+ objectType = lo & 0x07;
+ uint32 link = ((hi << 11) | (lo >> 21)) & 0x3FFFF8;
+ WriteLog("%08X: %08X %08X %s", address, hi, lo, opType[objectType]);
+
+ 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);
+
+ // Recursion needed to follow all links!
+ WriteLog("\n");
+ OPDumpObjectList(address + 8);
+
+ // Do the sanity check after recursive call: We may have already seen this...
+ // Sanity checking: If we've already visited this link, bail out!
+//disnowok: we added ourself above
+// for(uint32 i=0; i<numberOfLinks; i++)
+// {
+// if (address == objectLink[i])
+// return;
+// }
+ }
+
+ WriteLog("\n");
-// memory_free(op_blend_y);
-// memory_free(op_blend_cr);
+ 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");
+ return;
+ }
+
+ address = link;
+ objectLink[numberOfLinks++] = address;
+ }
+ while (objectType != 4);
+
+ WriteLog("\n");
}
+
+
//
// Object Processor memory access
// Memory range: F00010 - F00027
//
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;
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)
+{
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);
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);
+ 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);
}
//
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;
#define MEMCON2 0x02
#define HC 0x04
#define VC 0x06
+#define OLP 0x20 // Object list pointer
+#define OBF 0x26 // Object processor flag
#define VMODE 0x28
#define MODE 0x0006 // Line buffer to video generator mode
#define BGEN 0x0080 // Background enable (CRY & RGB16 only)
#define BORD1 0x2A // Border green/red values (8 BPP)
#define BORD2 0x2C // Border blue value (8 BPP)
#define HP 0x2E // Values range from 1 - 1024 (value written + 1)
-#define HBB 0x30
+#define HBB 0x30 // Horizontal blank begin
#define HBE 0x32
+#define HS 0x34 // Horizontal sync
+#define HVS 0x36 // Horizontal vertical sync
#define HDB1 0x38 // Horizontal display begin 1
#define HDB2 0x3A
#define HDE 0x3C
#define VP 0x3E // Value ranges from 1 - 2048 (value written + 1)
-#define VBB 0x40
+#define VBB 0x40 // Vertical blank begin
#define VBE 0x42
-#define VS 0x44
-#define VDB 0x46
+#define VS 0x44 // Vertical sync
+#define VDB 0x46 // Vertical display begin
#define VDE 0x48
-#define VI 0x4E
+#define VEB 0x4A // Vertical equalization begin
+#define VEE 0x4C // Vertical equalization end
+#define VI 0x4E // Vertical interrupt
#define PIT0 0x50
#define PIT1 0x52
-#define BG 0x58
+#define HEQ 0x54 // Horizontal equalization end
+#define BG 0x58 // Background color
#define INT1 0xE0
//NOTE: These arbitrary cutoffs are NOT taken into account for PAL jaguar screens. !!! FIX !!!
return;
#endif
-if (offset == 0xF00000 + MEMCON1)
- WriteLog("TOM: Memory Configuration 1 written by %s: %04X\n", whoName[who], data);
-if (offset == 0xF00000 + MEMCON2)
- WriteLog("TOM: Memory Configuration 2 written by %s: %04X\n", whoName[who], data);
+//if (offset == 0xF00000 + MEMCON1)
+// WriteLog("TOM: Memory Configuration 1 written by %s: %04X\n", whoName[who], data);
+//if (offset == 0xF00000 + MEMCON2)
+// WriteLog("TOM: Memory Configuration 2 written by %s: %04X\n", whoName[who], data);
if (offset >= 0xF02000 && offset <= 0xF020FF)
WriteLog("TOM: Write attempted to GPU register file by %s (unimplemented)!\n", whoName[who]);
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);
-if (offset == VDE)
- WriteLog("TOM: Vertical Display End written by %s: %u\n", whoName[who], data);
-if (offset == VP)
- WriteLog("TOM: Vertical Period written by %s: %u (%sinterlaced)\n", whoName[who], data, (data & 0x01 ? "non-" : ""));
+if (offset == MEMCON1)
+ WriteLog("TOM: Memory Config 1 written by %s: $%04X\n", whoName[who], data);
+if (offset == MEMCON2)
+ WriteLog("TOM: Memory Config 2 written by %s: $%04X\n", whoName[who], data);
+//if (offset == OLP)
+// WriteLog("TOM: Object List Pointer written by %s: $%04X\n", whoName[who], data);
+//if (offset == OLP + 2)
+// WriteLog("TOM: Object List Pointer +2 written by %s: $%04X\n", whoName[who], data);
+//if (offset == OBF)
+// WriteLog("TOM: Object Processor Flag 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 == BORD1)
+ WriteLog("TOM: Border 1 written by %s: $%04X\n", whoName[who], data);
+if (offset == BORD2)
+ WriteLog("TOM: Border 2 written by %s: $%04X\n", whoName[who], data);
+if (offset == HP)
+ WriteLog("TOM: Horizontal Period written by %s: %u (+1*2 = %u)\n", whoName[who], data, (data + 1) * 2);
+if (offset == HBB)
+ WriteLog("TOM: Horizontal Blank Begin written by %s: %u\n", whoName[who], data);
+if (offset == HBE)
+ WriteLog("TOM: Horizontal Blank End written by %s: %u\n", whoName[who], data);
+if (offset == HS)
+ WriteLog("TOM: Horizontal Sync written by %s: %u\n", whoName[who], data);
+if (offset == HVS)
+ WriteLog("TOM: Horizontal Vertical Sync written by %s: %u\n", whoName[who], data);
if (offset == HDB1)
WriteLog("TOM: Horizontal Display Begin 1 written by %s: %u\n", whoName[who], data);
if (offset == HDB2)
WriteLog("TOM: Horizontal Display Begin 2 written by %s: %u\n", whoName[who], data);
if (offset == HDE)
WriteLog("TOM: Horizontal Display End written by %s: %u\n", whoName[who], data);
-if (offset == HP)
- WriteLog("TOM: Horizontal Period written by %s: %u (+1*2 = %u)\n", whoName[who], data, (data + 1) * 2);
+if (offset == VP)
+ WriteLog("TOM: Vertical Period written by %s: %u (%sinterlaced)\n", whoName[who], data, (data & 0x01 ? "non-" : ""));
if (offset == VBB)
WriteLog("TOM: Vertical Blank Begin written by %s: %u\n", whoName[who], data);
if (offset == VBE)
WriteLog("TOM: Vertical Blank End written by %s: %u\n", whoName[who], data);
if (offset == VS)
WriteLog("TOM: Vertical Sync written by %s: %u\n", whoName[who], data);
+if (offset == VDB)
+ WriteLog("TOM: Vertical Display Begin written by %s: %u\n", whoName[who], data);
+if (offset == VDE)
+ WriteLog("TOM: Vertical Display End written by %s: %u\n", whoName[who], data);
+if (offset == VEB)
+ WriteLog("TOM: Vertical Equalization Begin written by %s: %u\n", whoName[who], data);
+if (offset == VEE)
+ WriteLog("TOM: Vertical Equalization End written by %s: %u\n", whoName[who], data);
if (offset == VI)
WriteLog("TOM: Vertical Interrupt written by %s: %u\n", whoName[who], data);
-if (offset == HBB)
- WriteLog("TOM: Horizontal Blank Begin written by %s: %u\n", whoName[who], data);
-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 == HEQ)
+ WriteLog("TOM: Horizontal Equalization End written by %s: %u\n", whoName[who], data);
+//if (offset == BG)
+// WriteLog("TOM: Background 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" : ""));