//
// Originally by David Raingeard (cal2)
// GCC/SDL port by Niels Wagenaar (Linux/WIN32) and Caz (BeOS)
-// Cleanups and endian wrongness amelioration by James L. Hammons
+// Cleanups and endian wrongness amelioration by James Hammons
// (C) 2010 Underground Software
//
-// JLH = James L. Hammons <jlhamm@acm.org>
+// JLH = James Hammons <jlhamm@acm.org>
//
// Who When What
// --- ---------- -------------------------------------------------------------
#include "gpu.h"
#include "jaguar.h"
#include "log.h"
-#include "m68k.h"
+#include "m68000/m68kinterface.h"
//#include "memory.h"
#include "op.h"
#include "settings.h"
#define BG 0x58 // Background color
#define INT1 0xE0
-//NOTE: These arbitrary cutoffs are NOT taken into account for PAL jaguar screens. !!! FIX !!!
+//NOTE: These arbitrary cutoffs are NOT taken into account for PAL jaguar screens. !!! FIX !!! [DONE]
// Arbitrary video cutoff values (i.e., first/last visible spots on a TV, in HC ticks)
+// Also note that VC is in *half* lines, i.e. divide by 2 to get the scanline
/*#define LEFT_VISIBLE_HC 208
#define RIGHT_VISIBLE_HC 1528//*/
-#define LEFT_VISIBLE_HC 208
-#define RIGHT_VISIBLE_HC 1488
+// These were right for Rayman, but that one is offset on a real TV too.
+//#define LEFT_VISIBLE_HC 208
+//#define RIGHT_VISIBLE_HC 1488
+// This is more like a real TV display...
+//#define LEFT_VISIBLE_HC (208 - 32)
+//#define RIGHT_VISIBLE_HC (1488 - 32)
+// Split the difference? (Seems to be OK for the most part...)
+
+// (-10 +10)*4 is for opening up the display by 16 pixels (may go to 20). Need to change VIRTUAL_SCREEN_WIDTH to match this as well (went from 320 to 340; this is 4 HCs per one of those pixels).
+#define LEFT_VISIBLE_HC (208 - 16 - (8 * 4))
+//#define RIGHT_VISIBLE_HC (1488 - 16 + (10 * 4))
+#define RIGHT_VISIBLE_HC (LEFT_VISIBLE_HC + (VIRTUAL_SCREEN_WIDTH * 4))
//#define TOP_VISIBLE_VC 25
//#define BOTTOM_VISIBLE_VC 503
#define TOP_VISIBLE_VC 31
//Are these PAL horizontals correct?
//They seem to be for the most part, but there are some games that seem to be
//shifted over to the right from this "window".
-#define LEFT_VISIBLE_HC_PAL 208
-#define RIGHT_VISIBLE_HC_PAL 1488
+#define LEFT_VISIBLE_HC_PAL (208 - 16 - (4 * 4))
+//#define RIGHT_VISIBLE_HC_PAL (1488 - 16 + (10 * 4))
+#define RIGHT_VISIBLE_HC_PAL (LEFT_VISIBLE_HC_PAL + (VIRTUAL_SCREEN_WIDTH * 4))
#define TOP_VISIBLE_VC_PAL 67
#define BOTTOM_VISIBLE_VC_PAL 579
//
void TOMExecHalfline(uint16 halfline, bool render)
{
+#warning "!!! Need to handle multiple fields properly !!!"
+ // We ignore the problem for now
+ halfline &= 0x7FF;
+
bool inActiveDisplayArea = true;
//Interlacing is still not handled correctly here... !!! FIX !!!
- if (halfline & 0x01) // Execute OP only on even lines (non-interlaced only!)
+ if (halfline & 0x01) // Execute OP only on even halflines (non-interlaced only!)
return;
//Hm, it seems that the OP needs to execute from zero, so let's try it:
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.
+
+
+What triggers this is writing $FFFF to VDE. This causes the OP start signal in VID to
+latch on, which in effect sets VDB to zero. So that much is correct. But the thing with
+Rayman is that it shouldn't cause the graphical glitches seen there, so still have to
+investigate what's going on there. By all rights, it shouldn't glitch because:
+
+00006C00: 0000000D 82008F73 (BRANCH) YPOS=494, CC=">", link=$00006C10
+00006C08: 000003FF 00008173 (BRANCH) YPOS=46, CC=">", link=$001FF800
+00006C10: 00000000 0000000C (STOP)
+001FF800: 12FC2BFF 02380000 (BITMAP)
+ 00008004 8180CFF1
+
+Even if the OP is running all the time, the link should tell it to stop at the right
+place (which it seems to do). But we still get glitchy screen.
+
+Seems the glitchy screen went away... Maybe the GPU alignment fixes fixed it???
+Just need to add the proper checking here then.
+
+Some numbers, courtesy of the Jaguar BIOS:
+// NTSC:
+VP, 523 // Vertical Period (1-based; in this case VP = 524)
+VBE, 24 // Vertical Blank End
+VDB, 38 // Vertical Display Begin
+VDE, 518 // Vertical Display End
+VBB, 500 // Vertical Blank Begin
+VS, 517 // Vertical Sync
+
+// PAL Jaguar
+VP, 623 // Vertical Period (1-based; in this case VP = 624)
+VBE, 34 // Vertical Blank End
+VDB, 38 // Vertical Display Begin
+VDE, 518 // Vertical Display End
+VBB, 600 // Vertical Blank Begin
+VS, 618 // Vertical Sync
+
+Numbers for KM, NTSC:
+KM: (Note that with VDE <= 507, the OP starts at VDB as expected)
+TOM: Vertical Display Begin written by M68K: 41
+TOM: Vertical Display End written by M68K: 2047
+TOM: Vertical Interrupt written by M68K: 491
*/
#if 1
+ // Initial values that "well behaved" programs use
+ uint16 startingHalfline = GET16(tomRam8, VDB);
+ uint16 endingHalfline = GET16(tomRam8, VDE);
+
+ // Simulate the OP start bug here!
+ // Really, this value is somewhere around 507 for an NTSC Jaguar. But this
+ // should work in a majority of cases, at least until we can figure it out properly.
+ if (endingHalfline > GET16(tomRam8, VP))
+ startingHalfline = 0;
+
+ if (halfline >= startingHalfline && halfline < endingHalfline)
+// if (halfline >= 0 && halfline < (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 (halfline >= (uint16)GET16(tomRam8, VDB) && halfline < (uint16)GET16(tomRam8, VDE))
{
if (render)
{
// TOM reset code
// Now PAL friendly!
//
+/*
+The values in TOMReset come from the Jaguar BIOS.
+These values are from BJL:
+
+NSTC:
+CLK2 181
+HP 844
+HBB 1713
+HBE 125
+HS 1741
+HVS 651
+HEQ 784
+HDE 1696
+HDB1 166
+HDB2 166
+VP 523
+VEE 6
+VBE 24
+VDB 46
+VDE 496
+VBB 500
+VEB 511
+VS 517
+
+PAL:
+CLK2 226
+HP 850
+HBB 1711
+HBE 158
+HS 1749
+HVS 601
+HEQ 787
+HDE 1696
+HDB1 166
+HDB2 166
+VP 625
+VEE 6
+VBE 34
+VDB 46
+VDE 429
+VBB 600
+VEB 613
+VS 618
+*/
void TOMReset(void)
{
OPReset();
{
SET16(tomRam8, MEMCON1, 0x1861);
SET16(tomRam8, MEMCON2, 0x35CC);
- SET16(tomRam8, HP, 844); // Horizontal Period (1-based; HP=845)
+ SET16(tomRam8, HP, 844); // Horizontal Period (1-based; HP=845)
SET16(tomRam8, HBB, 1713); // Horizontal Blank Begin
- SET16(tomRam8, HBE, 125); // Horizontal Blank End
+ SET16(tomRam8, HBE, 125); // Horizontal Blank End
SET16(tomRam8, HDE, 1665); // Horizontal Display End
SET16(tomRam8, HDB1, 203); // Horizontal Display Begin 1
- SET16(tomRam8, VP, 523); // Vertical Period (1-based; in this case VP = 524)
- SET16(tomRam8, VBE, 24); // Vertical Blank End
- SET16(tomRam8, VDB, 38); // Vertical Display Begin
- SET16(tomRam8, VDE, 518); // Vertical Display End
- SET16(tomRam8, VBB, 500); // Vertical Blank Begin
- SET16(tomRam8, VS, 517); // Vertical Sync
+ SET16(tomRam8, VP, 523); // Vertical Period (1-based; in this case VP = 524)
+ SET16(tomRam8, VBE, 24); // Vertical Blank End
+ SET16(tomRam8, VDB, 38); // Vertical Display Begin
+ SET16(tomRam8, VDE, 518); // Vertical Display End
+ SET16(tomRam8, VBB, 500); // Vertical Blank Begin
+ SET16(tomRam8, VS, 517); // Vertical Sync
SET16(tomRam8, VMODE, 0x06C1);
}
else // PAL Jaguar
{
SET16(tomRam8, MEMCON1, 0x1861);
SET16(tomRam8, MEMCON2, 0x35CC);
- SET16(tomRam8, HP, 850); // Horizontal Period
+ SET16(tomRam8, HP, 850); // Horizontal Period
SET16(tomRam8, HBB, 1711); // Horizontal Blank Begin
- SET16(tomRam8, HBE, 158); // Horizontal Blank End
+ SET16(tomRam8, HBE, 158); // Horizontal Blank End
SET16(tomRam8, HDE, 1665); // Horizontal Display End
SET16(tomRam8, HDB1, 203); // Horizontal Display Begin 1
- SET16(tomRam8, VP, 623); // Vertical Period (1-based; in this case VP = 624)
- SET16(tomRam8, VBE, 34); // Vertical Blank End
- SET16(tomRam8, VDB, 38); // Vertical Display Begin
- SET16(tomRam8, VDE, 518); // Vertical Display End
- SET16(tomRam8, VBB, 600); // Vertical Blank Begin
- SET16(tomRam8, VS, 618); // Vertical Sync
+ SET16(tomRam8, VP, 623); // Vertical Period (1-based; in this case VP = 624)
+ SET16(tomRam8, VBE, 34); // Vertical Blank End
+ SET16(tomRam8, VDB, 38); // Vertical Display Begin
+ SET16(tomRam8, VDE, 518); // Vertical Display End
+ SET16(tomRam8, VBB, 600); // Vertical Blank Begin
+ SET16(tomRam8, VS, 618); // Vertical Sync
SET16(tomRam8, VMODE, 0x06C1);
}