X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Ftom.cpp;h=845f1551f37f1b88548a3e796ccc39a977300ee6;hb=685bb45b7766e8a12cd0de8ee486b9a61183c425;hp=0489ad8c5387867c47364649bd0faa8e4c7ba7ec;hpb=371821533a5a070a15fa1e7f2da2de7b94731bda;p=virtualjaguar diff --git a/src/tom.cpp b/src/tom.cpp index 0489ad8..845f155 100644 --- a/src/tom.cpp +++ b/src/tom.cpp @@ -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 +// JLH = James Hammons // // Who When What // --- ---------- ------------------------------------------------------------- @@ -263,7 +263,7 @@ #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" @@ -308,13 +308,27 @@ #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). +//NB: Went back to 330. May shrink more. :-) +//#define LEFT_VISIBLE_HC (208 - 16 - (8 * 4)) +//#define LEFT_VISIBLE_HC (208 - 16 - (3 * 4)) +#define LEFT_VISIBLE_HC (208 - 16 - (1 * 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 @@ -323,8 +337,11 @@ //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 LEFT_VISIBLE_HC_PAL (208 - 16 - (-1 * 4)) +#define LEFT_VISIBLE_HC_PAL (208 - 16 - (-3 * 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 @@ -546,6 +563,7 @@ uint32 RGB16ToRGB32[0x10000]; uint32 CRY16ToRGB32[0x10000]; uint32 MIX16ToRGB32[0x10000]; + #warning "This is not endian-safe. !!! FIX !!!" void TOMFillLookupTables(void) { @@ -577,42 +595,50 @@ void TOMFillLookupTables(void) } } + void TOMSetPendingJERRYInt(void) { tom_jerry_int_pending = 1; } + void TOMSetPendingTimerInt(void) { tom_timer_int_pending = 1; } + void TOMSetPendingObjectInt(void) { tom_object_int_pending = 1; } + void TOMSetPendingGPUInt(void) { tom_gpu_int_pending = 1; } + void TOMSetPendingVideoInt(void) { tom_video_int_pending = 1; } + uint8 * TOMGetRamPointer(void) { return tomRam8; } + uint8 TOMGetVideoMode(void) { uint16 vmode = GET16(tomRam8, VMODE); return ((vmode & VARMOD) >> 6) | ((vmode & MODE) >> 1); } + //Used in only one place (and for debug purposes): OBJECTP.CPP #warning "Used in only one place (and for debug purposes): OBJECTP.CPP !!! FIX !!!" uint16 TOMGetVDB(void) @@ -620,6 +646,8 @@ uint16 TOMGetVDB(void) return GET16(tomRam8, VDB); } + +#define LEFT_BG_FIX // // 16 BPP CRY/RGB mixed mode rendering // @@ -634,15 +662,32 @@ void tom_render_16bpp_cry_rgb_mix_scanline(uint32 * backbuffer) //NOTE: May have to check HDB2 as well! // Get start position in HC ticks int16 startPos = GET16(tomRam8, HDB1) - (vjs.hardwareTypeNTSC ? LEFT_VISIBLE_HC : LEFT_VISIBLE_HC_PAL); + // Convert to pixels startPos /= pwidth; + if (startPos < 0) + // This is x2 because current_line_buffer is uint8 & we're in a 16bpp mode current_line_buffer += 2 * -startPos; else //This case doesn't properly handle the "start on the right side of virtual screen" case //Dunno why--looks Ok... -//What *is* for sure wrong is that it doesn't copy the linebuffer's BG pixels... +//What *is* for sure wrong is that it doesn't copy the linebuffer's BG pixels... [FIXED NOW] //This should likely be 4 instead of 2 (?--not sure) +// Actually, there should be NO multiplier, as startPos is expressed in PIXELS +// and so is the backbuffer. +#ifdef LEFT_BG_FIX + { + uint8 g = tomRam8[BORD1], r = tomRam8[BORD1 + 1], b = tomRam8[BORD2 + 1]; + uint32 pixel = 0x000000FF | (r << 24) | (g << 16) | (b << 8); + + for(int16 i=0; i 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) { @@ -931,6 +1068,7 @@ void tom_render_24bpp_scanline(uint32 * backbuffer) } } + // // TOM initialization // @@ -942,6 +1080,7 @@ void TOMInit(void) TOMReset(); } + void TOMDone(void) { OPDone(); @@ -957,6 +1096,7 @@ void TOMDone(void) // memory_free(tom_cry_rgb_mix_lut); } + uint32 TOMGetVideoModeWidth(void) { //These widths are pretty bogus. Should use HDB1/2 & HDE/HBB & PWIDTH to calc the width... @@ -1015,6 +1155,7 @@ uint32 TOMGetVideoModeWidth(void) // That's basically what we're doing now...! } + // *** SPECULATION *** // It might work better to virtualize the height settings, i.e., set the vertical // height at 240 lines and clip using the VDB and VDE/VP registers... @@ -1050,10 +1191,55 @@ uint32 TOMGetVideoModeHeight(void) return (vjs.hardwareTypeNTSC ? 240 : 256); } + // // 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 +1250,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); } @@ -1109,6 +1295,7 @@ void TOMReset(void) tomTimerCounter = 0; } + // // TOM byte access (read) // @@ -1144,6 +1331,7 @@ uint8 TOMReadByte(uint32 offset, uint32 who/*=UNKNOWN*/) return tomRam8[offset & 0x3FFF]; } + // // TOM word access (read) // @@ -1155,7 +1343,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) { @@ -1201,6 +1389,7 @@ if (offset >= 0xF02000 && offset <= 0xF020FF) return (TOMReadByte(offset, who) << 8) | TOMReadByte(offset + 1, who); } + #define TOM_STRICT_MEMORY_ACCESS // // TOM byte access (write) @@ -1284,6 +1473,7 @@ void TOMWriteByte(uint32 offset, uint8 data, uint32 who/*=UNKNOWN*/) tomRam8[offset & 0x3FFF] = data; } + // // TOM word access (write) // @@ -1316,7 +1506,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)) { @@ -1483,6 +1673,7 @@ if (offset == HEQ) #endif } + int TOMIRQEnabled(int irq) { // This is the correct byte in big endian... D'oh! @@ -1490,6 +1681,7 @@ int TOMIRQEnabled(int irq) return tomRam8[INT1 + 1/*0xE1*/] & (1 << irq); } + // NEW: // TOM Programmable Interrupt Timer handler // NOTE: TOM's PIT is only enabled if the prescaler is != 0 @@ -1497,6 +1689,7 @@ int TOMIRQEnabled(int irq) void TOMPITCallback(void); + void TOMResetPIT(void) { #ifndef NEW_TIMER_SYSTEM @@ -1519,6 +1712,7 @@ void TOMResetPIT(void) #endif } + // // TOM Programmable Interrupt Timer handler // NOTE: TOM's PIT is only enabled if the prescaler is != 0 @@ -1544,6 +1738,7 @@ void TOMExecPIT(uint32 cycles) } } + void TOMPITCallback(void) { // INT1_RREG |= 0x08; // Set TOM PIT interrupt pending @@ -1556,3 +1751,4 @@ void TOMPITCallback(void) TOMResetPIT(); } +