]> Shamusworld >> Repos - virtualjaguar/blobdiff - src/tom.cpp
Added RISC disassembly browser.
[virtualjaguar] / src / tom.cpp
index 0489ad8c5387867c47364649bd0faa8e4c7ba7ec..9569252d7441e0f5f8594fb1ffa3c31136e5089e 100644 (file)
@@ -3,10 +3,10 @@
 //
 // 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
 
@@ -777,10 +789,14 @@ void tom_render_16bpp_rgb_scanline(uint32 * backbuffer)
 //
 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:
@@ -793,13 +809,66 @@ No, the OP doesn't start until VDB, that much is certain. The thing is, VDB is t
 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)
                {
@@ -1054,6 +1123,50 @@ uint32 TOMGetVideoModeHeight(void)
 // 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();
@@ -1064,34 +1177,34 @@ void TOMReset(void)
        {
                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);
        }
 
@@ -1155,7 +1268,7 @@ uint16 TOMReadWord(uint32 offset, uint32 who/*=UNKNOWN*/)
        WriteLog("TOM: Reading word at %06X for %s\n", offset, whoName[who]);
 #endif
 if (offset >= 0xF02000 && offset <= 0xF020FF)
-       WriteLog("TOM: Read attempted from GPU register file by %s (unimplemented)!\n", whoName[who]);
+       WriteLog("TOM: ReadWord attempted from GPU register file by %s (unimplemented)!\n", whoName[who]);
 
        if (offset == 0xF000E0)
        {
@@ -1316,7 +1429,7 @@ void TOMWriteWord(uint32 offset, uint16 data, uint32 who/*=UNKNOWN*/)
 //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]);
+       WriteLog("TOM: WriteWord attempted to GPU register file by %s (unimplemented)!\n", whoName[who]);
 
        if ((offset >= GPU_CONTROL_RAM_BASE) && (offset < GPU_CONTROL_RAM_BASE+0x20))
        {