X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Ftom.cpp;h=08832a8ce3ccb3b3ed9c304c26cd5ca3e54df7a9;hb=6fb8c1441184b33847cfe668022aaf31b54a71e0;hp=cdf47979451ec617e799fb5f372a121d056eeb83;hpb=f548beede257a2252a2639e3fe03c7cda99433ed;p=virtualjaguar diff --git a/src/tom.cpp b/src/tom.cpp index cdf4797..08832a8 100644 --- a/src/tom.cpp +++ b/src/tom.cpp @@ -265,7 +265,7 @@ #include "log.h" #include "m68k.h" //#include "memory.h" -#include "objectp.h" +#include "op.h" #include "settings.h" #define NEW_TIMER_SYSTEM @@ -296,6 +296,8 @@ #define VDB 0x46 #define VDE 0x48 #define VI 0x4E +#define PIT0 0x50 +#define PIT1 0x52 #define BG 0x58 #define INT1 0xE0 @@ -330,7 +332,11 @@ uint32 tomTimerDivider; 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", @@ -696,7 +702,7 @@ void tom_render_24bpp_scanline(uint32 * backbuffer) current_line_buffer++; uint32 b = *current_line_buffer++; //hm. *backbuffer++ = 0xFF000000 | (b << 16) | (g << 8) | r; - *backbuffer++ = 0x000000FF | (r << 24) | (g << 16) | (r << 8); + *backbuffer++ = 0x000000FF | (r << 24) | (g << 16) | (b << 8); width--; } } @@ -753,15 +759,14 @@ void tom_render_16bpp_rgb_scanline(uint32 * backbuffer) } -void TOMResetBackbuffer(uint32 * backbuffer) +/*void TOMResetBackbuffer(uint32 * backbuffer) { TOMBackbuffer = backbuffer; -} +}*/ // // Process a single scanline // -uint32 tomDeviceWidth;//kludge void TOMExecScanline(uint16 scanline, bool render) { bool inActiveDisplayArea = true; @@ -770,7 +775,15 @@ void TOMExecScanline(uint16 scanline, bool render) if (scanline & 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: +// And it works! But need to do some optimizations in the OP to keep it from attempting +// 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... +#if 1 +// 16 isn't enough, and neither is 32 for raptgun. 32 fucks up Rayman if (scanline >= (uint16)GET16(tomRam8, VDB) && scanline < (uint16)GET16(tomRam8, VDE)) +// if (scanline >= ((uint16)GET16(tomRam8, VDB) - 32) && scanline < (uint16)GET16(tomRam8, VDE)) { if (render) { @@ -787,11 +800,35 @@ void TOMExecScanline(uint16 scanline, bool render) } else inActiveDisplayArea = false; +#else + inActiveDisplayArea = + (scanline >= (uint16)GET16(tomRam8, VDB) && scanline < (uint16)GET16(tomRam8, VDE) + ? true : false); - // Try to take PAL into account... + if (scanline < (uint16)GET16(tomRam8, VDE)) + { + if (render)//With JaguarExecuteNew() this is always true... + { + uint8 * current_line_buffer = (uint8 *)&tomRam8[0x1800]; + uint8 bgHI = tomRam8[BG], bgLO = tomRam8[BG + 1]; + + // Clear line buffer with BG + if (GET16(tomRam8, VMODE) & BGEN) // && (CRY or RGB16)... + for(uint32 i=0; i<720; i++) + *current_line_buffer++ = bgHI, *current_line_buffer++ = bgLO; + +// OPProcessList(scanline, render); +//This seems to take care of it... + OPProcessList(scanline, inActiveDisplayArea); + } + } +#endif + + // 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[((scanline - topVisible) / 2) * screenPitch]); // Here's our virtualized scanline code... @@ -802,7 +839,8 @@ void TOMExecScanline(uint16 scanline, bool render) //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 { /* @@ -866,7 +904,7 @@ void tom_render_24bpp_scanline(uint32 * backbuffer) 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); @@ -874,10 +912,6 @@ void tom_render_24bpp_scanline(uint32 * backbuffer) for(uint32 i=0; i= GPU_CONTROL_RAM_BASE) && (offset < GPU_CONTROL_RAM_BASE+0x20)) @@ -1102,13 +1136,14 @@ uint16 TOMReadWord(uint32 offset, uint32 who/*=UNKNOWN*/) //???Is this needed??? // offset &= 0xFF3FFF; #ifdef TOM_DEBUG - WriteLog("TOM: Reading word at %06X\n", offset); + 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]); if (offset == 0xF000E0) { + // For reading, should only return the lower 5 bits... uint16 data = (tom_jerry_int_pending << 4) | (tom_timer_int_pending << 3) | (tom_object_int_pending << 2) | (tom_gpu_int_pending << 1) | (tom_video_int_pending << 0); @@ -1150,17 +1185,33 @@ if (offset >= 0xF02000 && offset <= 0xF020FF) return (TOMReadByte(offset, who) << 8) | TOMReadByte(offset + 1, who); } +#define TOM_STRICT_MEMORY_ACCESS // // TOM byte access (write) // void TOMWriteByte(uint32 offset, uint8 data, uint32 who/*=UNKNOWN*/) { +#ifdef TOM_DEBUG + WriteLog("TOM: Writing byte %02X at %06X", data, offset); +#endif //???Is this needed??? // Perhaps on the writes--32-bit writes that is! And masked with FF7FFF... +#ifndef TOM_STRICT_MEMORY_ACCESS offset &= 0xFF3FFF; - +#else + // "Fast" (32-bit only) write access to the GPU +// if ((offset >= 0xF0A100) && (offset <= 0xF0BFFF)) + if ((offset >= 0xF08000) && (offset <= 0xF0BFFF)) + offset &= 0xFF7FFF; +#endif #ifdef TOM_DEBUG - WriteLog("TOM: Writing byte %02X at %06X\n", data, offset); + WriteLog(" -->[%06X] by %s\n", offset, whoName[who]); +#endif + +#ifdef TOM_STRICT_MEMORY_ACCESS + // Sanity check ("Aww, there ain't no Sanity Clause...") + if ((offset < 0xF00000) || (offset > 0xF03FFF)) + return; #endif if ((offset >= GPU_CONTROL_RAM_BASE) && (offset < GPU_CONTROL_RAM_BASE+0x20)) @@ -1222,12 +1273,28 @@ void TOMWriteByte(uint32 offset, uint8 data, uint32 who/*=UNKNOWN*/) // void TOMWriteWord(uint32 offset, uint16 data, uint32 who/*=UNKNOWN*/) { -//???Is this needed??? +#ifdef TOM_DEBUG + WriteLog("TOM: Writing byte %04X at %06X", data, offset); +#endif +//???Is this needed??? Yes, but we need to be more vigilant than this. +#ifndef TOM_STRICT_MEMORY_ACCESS offset &= 0xFF3FFF; - +#else + // "Fast" (32-bit only) write access to the GPU +// if ((offset >= 0xF0A100) && (offset <= 0xF0BFFF)) + if ((offset >= 0xF08000) && (offset <= 0xF0BFFF)) + offset &= 0xFF7FFF; +#endif #ifdef TOM_DEBUG - WriteLog("TOM: Writing word %04X at %06X\n", data, offset); + WriteLog(" -->[%06X] by %s\n", offset, whoName[who]); #endif + +#ifdef TOM_STRICT_MEMORY_ACCESS + // Sanity check + if ((offset < 0xF00000) || (offset > 0xF03FFF)) + return; +#endif + if (offset == 0xF00000 + MEMCON1) WriteLog("TOM: Memory Configuration 1 written by %s: %04X\n", whoName[who], data); if (offset == 0xF00000 + MEMCON2) @@ -1281,6 +1348,8 @@ if (offset >= 0xF02000 && offset <= 0xF020FF) tom_timer_int_pending = 0; if (data & 0x1000) tom_jerry_int_pending = 0; + +// return; } else if ((offset >= 0xF02200) && (offset <= 0xF0229F)) { @@ -1292,6 +1361,7 @@ if (offset >= 0xF02000 && offset <= 0xF020FF) // Writing to one CLUT writes to the other offset &= 0x5FF; // Mask out $F00600 (restrict to $F00400-5FF) // Watch out for unaligned writes here! (Not fixed yet) +#warning "!!! Watch out for unaligned writes here !!! FIX !!!" SET16(tomRam8, offset, data); SET16(tomRam8, offset + 0x200, data); } @@ -1307,8 +1377,9 @@ if (offset >= 0xF02000 && offset <= 0xF020FF) if (offset == 0x2E || offset == 0x36 || offset == 0x54) data &= 0x03FF; // These are all 10-bit registers - TOMWriteByte(offset, data >> 8, who); - TOMWriteByte(offset+1, data & 0xFF, who); +// Fix a lockup bug... :-P + 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); @@ -1318,6 +1389,8 @@ if (offset == VP) WriteLog("TOM: Vertical Period written by %s: %u (%sinterlaced)\n", whoName[who], data, (data & 0x01 ? "non-" : "")); 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) @@ -1336,10 +1409,21 @@ 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 == 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" : "")); // detect screen resolution changes //This may go away in the future, if we do the virtualized screen thing... //This may go away soon! +// TOM Shouldn't be mucking around with this, it's up to the host system to properly +// handle this kind of crap. +// NOTE: This is needed somehow, need to get rid of the dependency on this crap. +#warning "!!! Need to get rid of this dependency !!!" +#if 1 if ((offset >= 0x28) && (offset <= 0x4F)) { uint32 width = TOMGetVideoModeWidth(), height = TOMGetVideoModeHeight(); @@ -1354,6 +1438,7 @@ if (offset == VMODE) // ResizeScreen(tomWidth, tomHeight); } } +#endif } int TOMIRQEnabled(int irq) @@ -1410,7 +1495,7 @@ void TOMExecPIT(uint32 cycles) GPUSetIRQLine(GPUIRQ_TIMER, ASSERT_LINE); // GPUSetIRQLine does the 'IRQ enabled' checking if (TOMIRQEnabled(IRQ_TIMER)) - m68k_set_irq(7); // Cause a 68000 NMI... + m68k_set_irq(2); // Cause a 68000 IPL 2... TOMResetPIT(); } @@ -1425,7 +1510,7 @@ void TOMPITCallback(void) // if (INT1_WREG & 0x08) if (TOMIRQEnabled(IRQ_TIMER)) - m68k_set_irq(7); // Generate 68K NMI + m68k_set_irq(2); // Generate a 68K IPL 2... TOMResetPIT(); }