#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 !!!
int32 tomTimerCounter;
uint16 tom_jerry_int_pending, tom_timer_int_pending, tom_object_int_pending,
tom_gpu_int_pending, tom_video_int_pending;
-uint32 * TOMBackbuffer;
+
+// These are set by the "user" of the Jaguar core lib, since these are
+// OS/system dependent.
+uint32 * screenBuffer;
+uint32 screenPitch;
static const char * videoMode_to_str[8] =
{ "16 BPP CRY", "24 BPP RGB", "16 BPP DIRECT", "16 BPP RGB",
}
-void TOMResetBackbuffer(uint32 * backbuffer)
+/*void TOMResetBackbuffer(uint32 * backbuffer)
{
TOMBackbuffer = backbuffer;
-}
+}*/
//
// Process a single scanline
+// (this is bad terminology; each tick of the VC is actually a half-line)
//
-uint32 tomDeviceWidth;//kludge
-void TOMExecScanline(uint16 scanline, bool render)
+void TOMExecHalfline(uint16 halfline, bool render)
{
bool inActiveDisplayArea = true;
//Interlacing is still not handled correctly here... !!! FIX !!!
- if (scanline & 0x01) // Execute OP only on even lines (non-interlaced only!)
-// if (!(scanline & 0x01)) // Execute OP only on even lines (non-interlaced only!)
+ if (halfline & 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:
// to do a scanline render in the non-display area... [DONE]
//this seems to cause a regression in certain games, like rayman
//which means I have to dig thru the asic nets to see what's wrong...
+/*
+No, the OP doesn't start until VDB, that much is certain. The thing is, VDB is the
+HALF line that the OP starts on--which means that it needs to start at VDB / 2!!!
+
+Hrm, doesn't seem to be enough, though it should be... still sticks for 20 frames.
+*/
#if 1
- if (scanline >= (uint16)GET16(tomRam8, VDB) && scanline < (uint16)GET16(tomRam8, VDE))
+// 16 isn't enough, and neither is 32 for raptgun. 32 fucks up Rayman
+// if (halfline >= ((uint16)GET16(tomRam8, VDB) / 2) && halfline < ((uint16)GET16(tomRam8, VDE) / 2))
+ if (halfline >= (uint16)GET16(tomRam8, VDB) && halfline < (uint16)GET16(tomRam8, VDE))
+// if (halfline >= ((uint16)GET16(tomRam8, VDB) - 16) && halfline < (uint16)GET16(tomRam8, VDE))
+// if (halfline >= 20 && halfline < (uint16)GET16(tomRam8, VDE))
{
if (render)
{
for(uint32 i=0; i<720; i++)
*current_line_buffer++ = bgHI, *current_line_buffer++ = bgLO;
- OPProcessList(scanline, render);
+ OPProcessList(halfline, render);
}
}
else
inActiveDisplayArea = false;
#else
inActiveDisplayArea =
- (scanline >= (uint16)GET16(tomRam8, VDB) && scanline < (uint16)GET16(tomRam8, VDE)
+ (halfline >= (uint16)GET16(tomRam8, VDB) && halfline < (uint16)GET16(tomRam8, VDE)
? true : false);
- if (scanline < (uint16)GET16(tomRam8, VDE))
+ if (halfline < (uint16)GET16(tomRam8, VDE))
{
if (render)//With JaguarExecuteNew() this is always true...
{
for(uint32 i=0; i<720; i++)
*current_line_buffer++ = bgHI, *current_line_buffer++ = bgLO;
-// OPProcessList(scanline, render);
+// OPProcessList(halfline, render);
//This seems to take care of it...
- OPProcessList(scanline, inActiveDisplayArea);
+ OPProcessList(halfline, inActiveDisplayArea);
}
}
#endif
- // Try to take PAL into account...
+ // Try to take PAL into account... [We do now!]
uint16 topVisible = (vjs.hardwareTypeNTSC ? TOP_VISIBLE_VC : TOP_VISIBLE_VC_PAL),
bottomVisible = (vjs.hardwareTypeNTSC ? BOTTOM_VISIBLE_VC : BOTTOM_VISIBLE_VC_PAL);
+ uint32 * TOMCurrentLine = &(screenBuffer[((halfline - topVisible) / 2) * screenPitch]);
// Here's our virtualized scanline code...
- if (scanline >= topVisible && scanline < bottomVisible)
+ if (halfline >= topVisible && halfline < bottomVisible)
{
if (inActiveDisplayArea)
{
//NOTE: The following doesn't put BORDER color on the sides... !!! FIX !!!
#warning "The following doesn't put BORDER color on the sides... !!! FIX !!!"
if (vjs.renderType == RT_NORMAL)
- scanline_render[TOMGetVideoMode()](TOMBackbuffer);
+// scanline_render[TOMGetVideoMode()](TOMBackbuffer);
+ scanline_render[TOMGetVideoMode()](TOMCurrentLine);
else//TV type render
{
/*
else
{
// If outside of VDB & VDE, then display the border color
- uint32 * currentLineBuffer = TOMBackbuffer;
+ uint32 * currentLineBuffer = TOMCurrentLine;
uint8 g = tomRam8[BORD1], r = tomRam8[BORD1 + 1], b = tomRam8[BORD2 + 1];
//Hm. uint32 pixel = 0xFF000000 | (b << 16) | (g << 8) | r;
uint32 pixel = 0x000000FF | (r << 24) | (g << 16) | (b << 8);
for(uint32 i=0; i<tomWidth; i++)
*currentLineBuffer++ = pixel;
}
-
-#warning "!!! Need to move this to an interface file !!! FIX !!!"
-// TOMBackbuffer += GetSDLScreenWidthInPixels();
- TOMBackbuffer += tomDeviceWidth;
}
}
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" : ""));