X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;ds=sidebyside;f=src%2Ftom.cpp;h=046547248d5c41372490a2a99784e7fa476ee179;hb=166019baeee39e3867ecf6c4eddd0855dc3507a4;hp=69e02a8310bcc92604872c4b4112b23215dc3b97;hpb=de3c95ef6322202f6b06c769f2ea7856a20db35d;p=virtualjaguar diff --git a/src/tom.cpp b/src/tom.cpp index 69e02a8..0465472 100644 --- a/src/tom.cpp +++ b/src/tom.cpp @@ -11,9 +11,10 @@ // Who When What // --- ---------- ------------------------------------------------------------- // JLH 01/16/2010 Created this log ;-) +// JLH 01/20/2011 Change rendering to RGBA, removed unnecessary code // // Note: Endian wrongness probably stems from the MAME origins of this emu and -// the braindead way in which MAME handles memory. :-) +// the braindead way in which MAME used to handle memory. :-} // // Note: TOM has only a 16K memory space // @@ -264,9 +265,8 @@ #include "log.h" #include "m68k.h" //#include "memory.h" -#include "objectp.h" +#include "op.h" #include "settings.h" -#include "video.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 @@ -328,12 +330,8 @@ uint32 tomWidth, tomHeight; uint32 tomTimerPrescaler; uint32 tomTimerDivider; int32 tomTimerCounter; -//uint32 tom_scanline; -//uint32 hblankWidthInPixels = 0; uint16 tom_jerry_int_pending, tom_timer_int_pending, tom_object_int_pending, tom_gpu_int_pending, tom_video_int_pending; -//uint16 * tom_cry_rgb_mix_lut; -//int16 * TOMBackbuffer; uint32 * TOMBackbuffer; static const char * videoMode_to_str[8] = @@ -350,13 +348,8 @@ void tom_render_16bpp_direct_scanline(uint32 * backbuffer); void tom_render_16bpp_rgb_scanline(uint32 * backbuffer); void tom_render_16bpp_cry_rgb_mix_scanline(uint32 * backbuffer); -void tom_render_16bpp_cry_stretch_scanline(uint32 * backbuffer); -void tom_render_24bpp_stretch_scanline(uint32 * backbuffer); -void tom_render_16bpp_direct_stretch_scanline(uint32 * backbuffer); -void tom_render_16bpp_rgb_stretch_scanline(uint32 * backbuffer); -void tom_render_16bpp_cry_rgb_mix_stretch_scanline(uint32 * backbuffer); - -render_xxx_scanline_fn * scanline_render_normal[] = +//render_xxx_scanline_fn * scanline_render_normal[] = +render_xxx_scanline_fn * scanline_render[] = { tom_render_16bpp_cry_scanline, tom_render_24bpp_scanline, @@ -368,21 +361,6 @@ render_xxx_scanline_fn * scanline_render_normal[] = tom_render_16bpp_rgb_scanline }; -render_xxx_scanline_fn * scanline_render_stretch[] = -{ - tom_render_16bpp_cry_stretch_scanline, - tom_render_24bpp_stretch_scanline, - tom_render_16bpp_direct_stretch_scanline, - tom_render_16bpp_rgb_stretch_scanline, - tom_render_16bpp_cry_rgb_mix_stretch_scanline, - tom_render_24bpp_stretch_scanline, - tom_render_16bpp_direct_stretch_scanline, - tom_render_16bpp_rgb_stretch_scanline, -}; - -render_xxx_scanline_fn * scanline_render[8]; - - // Screen info for various games [PAL]... /* BIOS @@ -571,11 +549,6 @@ void TOMFillLookupTables(void) | ((i & 0xF100) << 16) // Red | ((i & 0x003F) << 18) // Green | ((i & 0x07C0) << 5); // Blue -/* -It does this: -0000 0000 0000 0000 RRRR RBBB BBGG GGGG -> AAAA AAAA BBBB BBBB GGGG GGGG RRRR RRRR - 5432 1543 2154 3210 5432 1543 5432 1054 5432 1543 -*/ for(uint32 i=0; i<0x10000; i++) { @@ -591,10 +564,6 @@ It does this: CRY16ToRGB32[i] = 0x000000FF | (r << 24) | (g << 16) | (b << 8); MIX16ToRGB32[i] = (i & 0x01 ? RGB16ToRGB32[i] : CRY16ToRGB32[i]); } - -// for(uint32 i=0; i<0x10000; i++) -// if (i & 0x01) -// MIX16ToRGB32[i] = RGB16ToRGB32[i]; } void TOMSetPendingJERRYInt(void) @@ -729,7 +698,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--; } } @@ -785,132 +754,6 @@ void tom_render_16bpp_rgb_scanline(uint32 * backbuffer) } } -///////////////////////////////////////////////////////////////////// -// This stuff may just go away by itself, especially if we do some // -// good old OpenGL goodness... // -///////////////////////////////////////////////////////////////////// - -void tom_render_16bpp_cry_rgb_mix_stretch_scanline(uint32 *backbuffer) -{ - uint16 width=tomWidth; - uint8 *current_line_buffer=(uint8*)&tomRam8[0x1800]; - - while (width) - { - uint16 color = *current_line_buffer++; - color <<= 8; - color |= *current_line_buffer++; - *backbuffer++ = MIX16ToRGB32[color]; - current_line_buffer += 2; - width--; - } -} - -void tom_render_16bpp_cry_stretch_scanline(uint32 *backbuffer) -{ - uint32 chrm, chrl, y; - - uint16 width=tomWidth; - uint8 *current_line_buffer=(uint8*)&tomRam8[0x1800]; - - while (width) - { - uint16 color; - color=*current_line_buffer++; - color<<=8; - color|=*current_line_buffer++; - - chrm = (color & 0xF000) >> 12; - chrl = (color & 0x0F00) >> 8; - y = (color & 0x00FF); - - uint16 red = ((((uint32)redcv[chrm][chrl])*y)>>11); - uint16 green = ((((uint32)greencv[chrm][chrl])*y)>>11); - uint16 blue = ((((uint32)bluecv[chrm][chrl])*y)>>11); - - uint16 color2; - color2=*current_line_buffer++; - color2<<=8; - color2|=*current_line_buffer++; - - chrm = (color2 & 0xF000) >> 12; - chrl = (color2 & 0x0F00) >> 8; - y = (color2 & 0x00FF); - - uint16 red2 = ((((uint32)redcv[chrm][chrl])*y)>>11); - uint16 green2 = ((((uint32)greencv[chrm][chrl])*y)>>11); - uint16 blue2 = ((((uint32)bluecv[chrm][chrl])*y)>>11); - - red=(red+red2)>>1; - green=(green+green2)>>1; - blue=(blue+blue2)>>1; - - *backbuffer++=(red<<10)|(green<<5)|blue; - width--; - } -} - -void tom_render_24bpp_stretch_scanline(uint32 *backbuffer) -{ - uint16 width=tomWidth; - uint8 *current_line_buffer=(uint8*)&tomRam8[0x1800]; - - while (width) - { - uint16 green=*current_line_buffer++; - uint16 red=*current_line_buffer++; - /*uint16 nc=*/current_line_buffer++; - uint16 blue=*current_line_buffer++; - red>>=3; - green>>=3; - blue>>=3; - *backbuffer++=(red<<10)|(green<<5)|blue; - current_line_buffer+=4; - width--; - } -} - -void tom_render_16bpp_direct_stretch_scanline(uint32 *backbuffer) -{ - uint16 width=tomWidth; - uint8 *current_line_buffer=(uint8*)&tomRam8[0x1800]; - - while (width) - { - uint16 color=*current_line_buffer++; - color<<=8; - color|=*current_line_buffer++; - color>>=1; - *backbuffer++=color; - current_line_buffer+=2; - width--; - } -} - -void tom_render_16bpp_rgb_stretch_scanline(uint32 *backbuffer) -{ - uint16 width=tomWidth; - uint8 *current_line_buffer=(uint8*)&tomRam8[0x1800]; - - while (width) - { - uint16 color1=*current_line_buffer++; - color1<<=8; - color1|=*current_line_buffer++; - color1>>=1; - uint16 color2=*current_line_buffer++; - color2<<=8; - color2|=*current_line_buffer++; - color2>>=1; - uint16 red=(((color1&0x7c00)>>10)+((color2&0x7c00)>>10))>>1; - uint16 green=(((color1&0x00003e0)>>5)+((color2&0x00003e0)>>5))>>1; - uint16 blue=(((color1&0x0000001f))+((color2&0x0000001f)))>>1; - - color1=(red<<10)|(blue<<5)|green; - *backbuffer++=color1; - width--; - } -} void TOMResetBackbuffer(uint32 * backbuffer) { @@ -929,6 +772,11 @@ 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 +#if 1 if (scanline >= (uint16)GET16(tomRam8, VDB) && scanline < (uint16)GET16(tomRam8, VDE)) { if (render) @@ -946,6 +794,29 @@ void TOMExecScanline(uint16 scanline, bool render) } else inActiveDisplayArea = false; +#else + inActiveDisplayArea = + (scanline >= (uint16)GET16(tomRam8, VDB) && scanline < (uint16)GET16(tomRam8, VDE) + ? true : false); + + 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... @@ -1045,12 +916,10 @@ void tom_render_24bpp_scanline(uint32 * backbuffer) // void TOMInit(void) { + TOMFillLookupTables(); OPInit(); BlitterInit(); TOMReset(); - // Setup the non-stretchy scanline rendering... - memcpy(scanline_render, scanline_render_normal, sizeof(scanline_render)); - TOMFillLookupTables(); } void TOMDone(void) @@ -1068,11 +937,6 @@ void TOMDone(void) // memory_free(tom_cry_rgb_mix_lut); } -/*uint32 tom_getHBlankWidthInPixels(void) -{ - return hblankWidthInPixels; -}*/ - uint32 TOMGetVideoModeWidth(void) { //These widths are pretty bogus. Should use HDB1/2 & HDE/HBB & PWIDTH to calc the width... @@ -1223,7 +1087,6 @@ void TOMReset(void) tomTimerPrescaler = 0; // TOM PIT is disabled tomTimerDivider = 0; tomTimerCounter = 0; - memcpy(scanline_render, scanline_render_normal, sizeof(scanline_render)); } // @@ -1238,7 +1101,7 @@ uint8 TOMReadByte(uint32 offset, uint32 who/*=UNKNOWN*/) // offset &= 0xFF3FFF; #ifdef TOM_DEBUG - WriteLog("TOM: Reading byte at %06X\n", offset); + WriteLog("TOM: Reading byte at %06X for %s\n", offset, whoName[who]); #endif if ((offset >= GPU_CONTROL_RAM_BASE) && (offset < GPU_CONTROL_RAM_BASE+0x20)) @@ -1269,13 +1132,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); @@ -1317,17 +1181,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)) @@ -1389,12 +1269,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) @@ -1448,6 +1344,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)) { @@ -1459,6 +1357,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); } @@ -1474,8 +1373,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); @@ -1503,10 +1403,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(); @@ -1521,6 +1432,7 @@ if (offset == VMODE) // ResizeScreen(tomWidth, tomHeight); } } +#endif } int TOMIRQEnabled(int irq) @@ -1530,18 +1442,6 @@ int TOMIRQEnabled(int irq) return tomRam8[INT1 + 1/*0xE1*/] & (1 << irq); } -//unused -/*void tom_set_irq_latch(int irq, int enabled) -{ - tomRam8[0xE0] = (tomRam8[0xE0] & (~(1<