From: Shamus Hammons Date: Sat, 3 Oct 2015 02:28:52 +0000 (-0500) Subject: Added logging of GPU/DSP states on exit. X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?p=virtualjaguar;a=commitdiff_plain;h=240a6df48aebb5e17f82452c32e770cdfe9b5d5e Added logging of GPU/DSP states on exit. --- diff --git a/cross-compile b/cross-compile index 285bb00..852ec95 100755 --- a/cross-compile +++ b/cross-compile @@ -6,18 +6,21 @@ # (C) 2012 Underground Software # #NOPE, doesn't work: PREFIX=i686-pc-mingw32.static -echo "Cross compiling for Win32..." -#echo "Cross compiling for Win64..." -export PATH=/opt/mxe/usr/bin:$PATH #rm makefile-qt -#/opt/mxe/usr/bin/i686-pc-mingw32.static-qmake -o makefile-qt -#make CROSS=i686-pc-mingw32.static- +echo "Cross compiling for Win32..." +SUFFIX=-win32 +export PATH=/opt/mxe-32/usr/bin:$PATH +/opt/mxe-32/usr/bin/i686-w64-mingw32.static-qmake-qt5 -o makefile-qt +make CROSS=i686-w64-mingw32.static- -/opt/mxe/usr/bin/x86_64-w64-mingw32.static-qmake-qt5 -o makefile-qt -make CROSS=x86_64-w64-mingw32.static- +#echo "Cross compiling for Win64..." +#SUFFIX=-win64 +#export PATH=/opt/mxe/usr/bin:$PATH +#/opt/mxe/usr/bin/x86_64-w64-mingw32.static-qmake-qt5 -o makefile-qt +#make CROSS=x86_64-w64-mingw32.static- #rel=`svn info | grep Revision | cut -f 2 -d ' '` rel=`git log -1 --pretty=format:%ci | cut -d ' ' -f 1 | tr -d -` -cd release && upx -9v virtualjaguar.exe && zip -9v vj-$rel.zip virtualjaguar.exe +cd release && upx -9v virtualjaguar.exe && zip -9v vj-$rel-${SUFFIX}.zip virtualjaguar.exe diff --git a/src/dsp.cpp b/src/dsp.cpp index e255cde..8853f94 100644 --- a/src/dsp.cpp +++ b/src/dsp.cpp @@ -1298,60 +1298,53 @@ void DSPDumpRegisters(void) void DSPDone(void) { - int i, j; + WriteLog("\n\n---------------------------------------------------------------------\n"); + WriteLog("DSP I/O Registers\n"); + WriteLog("---------------------------------------------------------------------\n"); + WriteLog("F1%04X (D_FLAGS): $%06X\n", 0xA100, (dsp_flags & 0xFFFFFFF8) | (dsp_flag_n << 2) | (dsp_flag_c << 1) | dsp_flag_z); + WriteLog("F1%04X (D_MTXC): $%04X\n", 0xA104, dsp_matrix_control); + WriteLog("F1%04X (D_MTXA): $%04X\n", 0xA108, dsp_pointer_to_matrix); + WriteLog("F1%04X (D_END): $%02X\n", 0xA10C, dsp_data_organization); + WriteLog("F1%04X (D_PC): $%06X\n", 0xA110, dsp_pc); + WriteLog("F1%04X (D_CTRL): $%06X\n", 0xA114, dsp_control); + WriteLog("F1%04X (D_MOD): $%08X\n", 0xA118, dsp_modulo); + WriteLog("F1%04X (D_REMAIN): $%08X\n", 0xA11C, dsp_remain); + WriteLog("F1%04X (D_DIVCTRL): $%02X\n", 0xA11C, dsp_div_control); + WriteLog("F1%04X (D_MACHI): $%02X\n", 0xA120, (dsp_acc >> 32) & 0xFF); + WriteLog("---------------------------------------------------------------------\n\n\n"); + WriteLog("DSP: Stopped at PC=%08X dsp_modulo=%08X (dsp was%s running)\n", dsp_pc, dsp_modulo, (DSP_RUNNING ? "" : "n't")); WriteLog("DSP: %sin interrupt handler\n", (dsp_flags & IMASK ? "" : "not ")); - // get the active interrupt bits + // Get the active interrupt bits int bits = ((dsp_control >> 10) & 0x20) | ((dsp_control >> 6) & 0x1F); - // get the interrupt mask + // Get the interrupt mask int mask = ((dsp_flags >> 11) & 0x20) | ((dsp_flags >> 4) & 0x1F); WriteLog("DSP: pending=$%X enabled=$%X (%s%s%s%s%s%s)\n", bits, mask, (mask & 0x01 ? "CPU " : ""), (mask & 0x02 ? "I2S " : ""), (mask & 0x04 ? "Timer0 " : ""), (mask & 0x08 ? "Timer1 " : ""), (mask & 0x10 ? "Ext0 " : ""), (mask & 0x20 ? "Ext1" : "")); - WriteLog("\nRegisters bank 0\n"); - - for(int j=0; j<8; j++) - { - WriteLog("\tR%02i=%08X R%02i=%08X R%02i=%08X R%02i=%08X\n", - (j << 2) + 0, dsp_reg_bank_0[(j << 2) + 0], - (j << 2) + 1, dsp_reg_bank_0[(j << 2) + 1], - (j << 2) + 2, dsp_reg_bank_0[(j << 2) + 2], - (j << 2) + 3, dsp_reg_bank_0[(j << 2) + 3]); - } - - WriteLog("\nRegisters bank 1\n"); - - for (j=0; j<8; j++) - { - WriteLog("\tR%02i=%08X R%02i=%08X R%02i=%08X R%02i=%08X\n", - (j << 2) + 0, dsp_reg_bank_1[(j << 2) + 0], - (j << 2) + 1, dsp_reg_bank_1[(j << 2) + 1], - (j << 2) + 2, dsp_reg_bank_1[(j << 2) + 2], - (j << 2) + 3, dsp_reg_bank_1[(j << 2) + 3]); - } - + DSPDumpRegisters(); WriteLog("\n"); static char buffer[512]; - j = DSP_WORK_RAM_BASE; + int j = DSP_WORK_RAM_BASE; while (j <= 0xF1CFFF) { uint32_t oldj = j; j += dasmjag(JAGUAR_DSP, buffer, j); WriteLog("\t%08X: %s\n", oldj, buffer); - }//*/ + } WriteLog("DSP opcodes use:\n"); - for (i=0;i<64;i++) + for(int i=0; i<64; i++) { if (dsp_opcode_use[i]) WriteLog("\t%s %i\n", dsp_opcode_str[i], dsp_opcode_use[i]); - }//*/ + } } diff --git a/src/gpu.cpp b/src/gpu.cpp index fbf26a0..9ee4264 100644 --- a/src/gpu.cpp +++ b/src/gpu.cpp @@ -319,9 +319,10 @@ static uint32_t gpu_pointer_to_matrix; static uint32_t gpu_data_organization; static uint32_t gpu_control; static uint32_t gpu_div_control; -// There is a distinct advantage to having these separated out--there's no need to clear -// a bit before writing a result. I.e., if the result of an operation leaves a zero in -// the carry flag, you don't have to zero gpu_flag_c before you can write that zero! +// There is a distinct advantage to having these separated out--there's no need +// to clear a bit before writing a result. I.e., if the result of an operation +// leaves a zero in the carry flag, you don't have to zero gpu_flag_c before +// you can write that zero! static uint8_t gpu_flag_z, gpu_flag_n, gpu_flag_c; uint32_t gpu_reg_bank_0[32]; uint32_t gpu_reg_bank_1[32]; @@ -1050,11 +1051,13 @@ void GPUReset(void) *((uint32_t *)(&gpu_ram_8[i])) = rand(); } + uint32_t GPUReadPC(void) { return gpu_pc; } + void GPUResetStats(void) { for(uint32_t i=0; i<64; i++) @@ -1062,6 +1065,7 @@ void GPUResetStats(void) WriteLog("--> GPU stats were reset!\n"); } + void GPUDumpDisassembly(void) { char buffer[512]; @@ -1076,6 +1080,7 @@ void GPUDumpDisassembly(void) } } + void GPUDumpRegisters(void) { WriteLog("\n---[GPU flags: NCZ %d%d%d]-----------------------\n", gpu_flag_n, gpu_flag_c, gpu_flag_z); @@ -1099,6 +1104,7 @@ void GPUDumpRegisters(void) } } + void GPUDumpMemory(void) { WriteLog("\n---[GPU data at 00F03000]---------------------------\n"); @@ -1107,8 +1113,23 @@ void GPUDumpMemory(void) gpu_ram_8[i+1], gpu_ram_8[i+2], gpu_ram_8[i+3]); } + void GPUDone(void) { + WriteLog("\n\n---------------------------------------------------------------------\n"); + WriteLog("GPU I/O Registers\n"); + WriteLog("---------------------------------------------------------------------\n"); + WriteLog("F0%04X (G_FLAGS): $%06X\n", 0x2100, (gpu_flags & 0xFFFFFFF8) | (gpu_flag_n << 2) | (gpu_flag_c << 1) | gpu_flag_z); + WriteLog("F0%04X (G_MTXC): $%04X\n", 0x2104, gpu_matrix_control); + WriteLog("F0%04X (G_MTXA): $%04X\n", 0x2108, gpu_pointer_to_matrix); + WriteLog("F0%04X (G_END): $%02X\n", 0x210C, gpu_data_organization); + WriteLog("F0%04X (G_PC): $%06X\n", 0x2110, gpu_pc); + WriteLog("F0%04X (G_CTRL): $%06X\n", 0x2114, gpu_control); + WriteLog("F0%04X (G_HIDATA): $%08X\n", 0x2118, gpu_hidata); + WriteLog("F0%04X (G_REMAIN): $%08X\n", 0x211C, gpu_remain); + WriteLog("F0%04X (G_DIVCTRL): $%02X\n", 0x211C, gpu_div_control); + WriteLog("---------------------------------------------------------------------\n\n\n"); + WriteLog("GPU: Stopped at PC=%08X (GPU %s running)\n", (unsigned int)gpu_pc, GPU_RUNNING ? "was" : "wasn't"); // Get the interrupt latch & enable bits @@ -1125,12 +1146,9 @@ void GPUDone(void) WriteLog("\t%17s %lu\n", gpu_opcode_str[i], gpu_opcode_use[i]); } WriteLog("\n"); - -// memory_free(gpu_ram_8); -// memory_free(gpu_reg_bank_0); -// memory_free(gpu_reg_bank_1); } + // // Main GPU execution core // diff --git a/src/gui/debug/opbrowser.cpp b/src/gui/debug/opbrowser.cpp index 6b3ff3e..5e1d405 100644 --- a/src/gui/debug/opbrowser.cpp +++ b/src/gui/debug/opbrowser.cpp @@ -107,9 +107,9 @@ void OPBrowserWindow::DiscoverObjects(uint32_t address) if (objectType == 3) { - // Branch if YPOS < 2047 can be treated as a GOTO, so don't do any - // discovery in that case. Otherwise, have at it: - if ((lo & 0xFFFF) != 0x7FFB) + // Branch if YPOS < 2047 (or YPOS > 0) can be treated as a GOTO, so + // don't do any discovery in that case. Otherwise, have at it: + if (((lo & 0xFFFF) != 0x7FFB) && ((lo & 0xFFFF) != 0x8003)) // Recursion needed to follow all links! This does depth-first // recursion on the not-taken objects DiscoverObjects(address + 8); diff --git a/src/op.cpp b/src/op.cpp index f4f858d..f8132e4 100644 --- a/src/op.cpp +++ b/src/op.cpp @@ -230,9 +230,9 @@ void OPDiscoverObjects(uint32_t address) if (objectType == 3) { - // Branch if YPOS < 2047 can be treated as a GOTO, so don't do any - // discovery in that case. Otherwise, have at it: - if ((lo & 0xFFFF) != 0x7FFB) + // Branch if YPOS < 2047 (or YPOS > 0) can be treated as a GOTO, so + // don't do any discovery in that case. Otherwise, have at it: + if (((lo & 0xFFFF) != 0x7FFB) && ((lo & 0xFFFF) != 0x8003)) // Recursion needed to follow all links! This does depth-first // recursion on the not-taken objects OPDiscoverObjects(address + 8); diff --git a/src/tom.cpp b/src/tom.cpp index 111adfd..3d6243b 100644 --- a/src/tom.cpp +++ b/src/tom.cpp @@ -3,19 +3,16 @@ // // Originally by David Raingeard (cal2) // GCC/SDL port by Niels Wagenaar (Linux/WIN32) and Caz (BeOS) -// Cleanups and endian wrongness amelioration by James Hammons +// Cleanups, endian wrongness amelioration, and extensive fixes by James Hammons // (C) 2010 Underground Software // // JLH = James Hammons // // 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 used to handle memory. :-} -// // Note: TOM has only a 16K memory space // // ------------------------------------------------------------ @@ -276,42 +273,41 @@ #define MEMCON2 0x02 #define HC 0x04 #define VC 0x06 -#define OLP 0x20 // Object list pointer -#define OBF 0x26 // Object processor flag +#define OLP 0x20 // Object list pointer +#define OBF 0x26 // Object processor flag #define VMODE 0x28 -#define MODE 0x0006 // Line buffer to video generator mode -#define BGEN 0x0080 // Background enable (CRY & RGB16 only) -#define VARMOD 0x0100 // Mixed CRY/RGB16 mode (only works in MODE 0!) -#define PWIDTH 0x0E00 // Pixel width in video clock cycles (value written + 1) -#define BORD1 0x2A // Border green/red values (8 BPP) -#define BORD2 0x2C // Border blue value (8 BPP) -#define HP 0x2E // Values range from 1 - 1024 (value written + 1) -#define HBB 0x30 // Horizontal blank begin +#define MODE 0x0006 // Line buffer to video generator mode +#define BGEN 0x0080 // Background enable (CRY & RGB16 only) +#define VARMOD 0x0100 // Mixed CRY/RGB16 mode (only works in MODE 0!) +#define PWIDTH 0x0E00 // Pixel width in video clock cycles (value written + 1) +#define BORD1 0x2A // Border green/red values (8 BPP) +#define BORD2 0x2C // Border blue value (8 BPP) +#define HP 0x2E // Values range from 1 - 1024 (value written + 1) +#define HBB 0x30 // Horizontal blank begin #define HBE 0x32 -#define HS 0x34 // Horizontal sync -#define HVS 0x36 // Horizontal vertical sync -#define HDB1 0x38 // Horizontal display begin 1 +#define HS 0x34 // Horizontal sync +#define HVS 0x36 // Horizontal vertical sync +#define HDB1 0x38 // Horizontal display begin 1 #define HDB2 0x3A #define HDE 0x3C -#define VP 0x3E // Value ranges from 1 - 2048 (value written + 1) -#define VBB 0x40 // Vertical blank begin +#define VP 0x3E // Value ranges from 1 - 2048 (value written + 1) +#define VBB 0x40 // Vertical blank begin #define VBE 0x42 -#define VS 0x44 // Vertical sync -#define VDB 0x46 // Vertical display begin +#define VS 0x44 // Vertical sync +#define VDB 0x46 // Vertical display begin #define VDE 0x48 -#define VEB 0x4A // Vertical equalization begin -#define VEE 0x4C // Vertical equalization end -#define VI 0x4E // Vertical interrupt +#define VEB 0x4A // Vertical equalization begin +#define VEE 0x4C // Vertical equalization end +#define VI 0x4E // Vertical interrupt #define PIT0 0x50 #define PIT1 0x52 -#define HEQ 0x54 // Horizontal equalization end -#define BG 0x58 // Background color +#define HEQ 0x54 // Horizontal equalization end +#define BG 0x58 // Background color #define INT1 0xE0 #define INT2 0xE2 -//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) +// 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//*/ @@ -560,6 +556,7 @@ Trevor McFur Vertical resolution: 238 lines */ +// 16-bit color lookup tables uint32_t RGB16ToRGB32[0x10000]; uint32_t CRY16ToRGB32[0x10000]; uint32_t MIX16ToRGB32[0x10000]; @@ -571,12 +568,7 @@ void TOMFillLookupTables(void) // NOTE: Jaguar 16-bit (non-CRY) color is RBG 556 like so: // RRRR RBBB BBGG GGGG for(uint32_t i=0; i<0x10000; i++) -//hm. RGB16ToRGB32[i] = 0xFF000000 -// | ((i & 0xF100) >> 8) | ((i & 0xE000) >> 13) -// | ((i & 0x07C0) << 13) | ((i & 0x0700) << 8) -// | ((i & 0x003F) << 10) | ((i & 0x0030) << 4); RGB16ToRGB32[i] = 0x000000FF -// | ((i & 0xF100) << 16) // Red | ((i & 0xF800) << 16) // Red | ((i & 0x003F) << 18) // Green | ((i & 0x07C0) << 5); // Blue @@ -591,7 +583,6 @@ void TOMFillLookupTables(void) g = (((uint32_t)greencv[cyan][red]) * intensity) >> 8, b = (((uint32_t)bluecv[cyan][red]) * intensity) >> 8; -//hm. CRY16ToRGB32[i] = 0xFF000000 | (b << 16) | (g << 8) | r; CRY16ToRGB32[i] = 0x000000FF | (r << 24) | (g << 16) | (b << 8); MIX16ToRGB32[i] = (i & 0x01 ? RGB16ToRGB32[i] : CRY16ToRGB32[i]); } @@ -727,6 +718,7 @@ void tom_render_16bpp_cry_scanline(uint32_t * backbuffer) //NOTE: May have to check HDB2 as well! int16_t startPos = GET16(tomRam8, HDB1) - (vjs.hardwareTypeNTSC ? LEFT_VISIBLE_HC : LEFT_VISIBLE_HC_PAL);// Get start position in HC ticks startPos /= pwidth; + if (startPos < 0) current_line_buffer += 2 * -startPos; else @@ -769,6 +761,7 @@ void tom_render_24bpp_scanline(uint32_t * backbuffer) //NOTE: May have to check HDB2 as well! int16_t startPos = GET16(tomRam8, HDB1) - (vjs.hardwareTypeNTSC ? LEFT_VISIBLE_HC : LEFT_VISIBLE_HC_PAL); // Get start position in HC ticks startPos /= pwidth; + if (startPos < 0) current_line_buffer += 4 * -startPos; else @@ -793,7 +786,6 @@ void tom_render_24bpp_scanline(uint32_t * backbuffer) uint32_t r = *current_line_buffer++; current_line_buffer++; uint32_t b = *current_line_buffer++; -//hm. *backbuffer++ = 0xFF000000 | (b << 16) | (g << 8) | r; *backbuffer++ = 0x000000FF | (r << 24) | (g << 16) | (b << 8); width--; } @@ -891,7 +883,6 @@ 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 @@ -945,12 +936,6 @@ TOM: Vertical Interrupt written by M68K: 491 startingHalfline = 0; if ((halfline >= startingHalfline) && (halfline < endingHalfline)) -// if (halfline >= 0 && halfline < (uint16_t)GET16(tomRam8, VDE)) -// 16 isn't enough, and neither is 32 for raptgun. 32 fucks up Rayman -// if (halfline >= ((uint16_t)GET16(tomRam8, VDB) / 2) && halfline < ((uint16_t)GET16(tomRam8, VDE) / 2)) -// if (halfline >= ((uint16_t)GET16(tomRam8, VDB) - 16) && halfline < (uint16_t)GET16(tomRam8, VDE)) -// if (halfline >= 20 && halfline < (uint16_t)GET16(tomRam8, VDE)) -// if (halfline >= (uint16_t)GET16(tomRam8, VDB) && halfline < (uint16_t)GET16(tomRam8, VDE)) { if (render) { @@ -1085,22 +1070,15 @@ void TOMDone(void) TOMDumpIORegistersToLog(); OPDone(); BlitterDone(); - WriteLog("TOM: Resolution %i x %i %s\n", TOMGetVideoModeWidth(), TOMGetVideoModeHeight(), - videoMode_to_str[TOMGetVideoMode()]); -// WriteLog("\ntom: object processor:\n"); -// WriteLog("tom: pointer to object list: 0x%.8x\n",op_get_list_pointer()); -// WriteLog("tom: INT1=0x%.2x%.2x\n",TOMReadByte(0xf000e0),TOMReadByte(0xf000e1)); + WriteLog("TOM: Resolution %i x %i %s\n", TOMGetVideoModeWidth(), + TOMGetVideoModeHeight(), videoMode_to_str[TOMGetVideoMode()]); } uint32_t TOMGetVideoModeWidth(void) { - //These widths are pretty bogus. Should use HDB1/2 & HDE/HBB & PWIDTH to calc the width... -// uint32_t width[8] = { 1330, 665, 443, 332, 266, 222, 190, 166 }; -//Temporary, for testing Doom... -// uint32_t width[8] = { 1330, 665, 443, 332, 266, 222, 190, 332 }; - - // Note that the following PWIDTH values have the following pixel aspect ratios: + // Note that the following PWIDTH values have the following pixel aspect + // ratios: // PWIDTH = 1 -> 0.25:1 (1:4) pixels (X:Y ratio) // PWIDTH = 2 -> 0.50:1 (1:2) pixels // PWIDTH = 3 -> 0.75:1 (3:4) pixels @@ -1110,80 +1088,21 @@ uint32_t TOMGetVideoModeWidth(void) // PWIDTH = 7 -> 1.75:1 (7:4) pixels // PWIDTH = 8 -> 2.00:1 (2:1) pixels - // Also note that the JTRM says that PWIDTH of 4 gives pixels that are "about" square-- - // this implies that the other modes have pixels that are *not* square! + // Also note that the JTRM says that PWIDTH of 4 gives pixels that are + // "about" square--this implies that the other modes have pixels that are + // *not* square (and they aren't)! // Also, I seriously doubt that you will see any games that use PWIDTH = 1! - // NOTE: Even though the PWIDTH value is + 1, here we're using a zero-based index and - // so we don't bother to add one... -// return width[(GET16(tomRam8, VMODE) & PWIDTH) >> 9]; - - // Now, we just calculate it... -/* uint16_t hdb1 = GET16(tomRam8, HDB1), hde = GET16(tomRam8, HDE), - hbb = GET16(tomRam8, HBB), pwidth = ((GET16(tomRam8, VMODE) & PWIDTH) >> 9) + 1; -// return ((hbb < hde ? hbb : hde) - hdb1) / pwidth; -//Temporary, for testing Doom... - return ((hbb < hde ? hbb : hde) - hdb1) / (pwidth == 8 ? 4 : pwidth);*/ - - // To make it easier to make a quasi-fixed display size, we restrict the viewing - // area to an arbitrary range of the Horizontal Count. + // To make it easier to make a quasi-fixed display size, we restrict the + // viewing area to an arbitrary range of the Horizontal Count. uint16_t pwidth = ((GET16(tomRam8, VMODE) & PWIDTH) >> 9) + 1; return (vjs.hardwareTypeNTSC ? RIGHT_VISIBLE_HC - LEFT_VISIBLE_HC : RIGHT_VISIBLE_HC_PAL - LEFT_VISIBLE_HC_PAL) / pwidth; -//Temporary, for testing Doom... -// return (RIGHT_VISIBLE_HC - LEFT_VISIBLE_HC) / (pwidth == 8 ? 4 : pwidth); -//// return (RIGHT_VISIBLE_HC - LEFT_VISIBLE_HC) / (pwidth == 4 ? 8 : pwidth); - -// More speculating... -// According to the JTRM, the number of potential pixels across is given by the -// Horizontal Period (HP - in NTSC this is 845). The Horizontal Count counts from -// zero to this value twice per scanline (the high bit is set on the second count). -// HBE and HBB define the absolute "black" limits of the screen, while HDB1/2 and -// HDE determine the extent of the OP "on" time. I.e., when the OP is turned on by -// HDB1, it starts fetching the line from position 0 in LBUF. - -// The trick, it would seem, is to figure out how long the typical visible scanline -// of a TV is in HP ticks and limit the visible area to that (divided by PWIDTH, of -// course). Using that length, we can establish an "absolute left display limit" with -// which to measure HBB & HDB1/2 against when rendering LBUF (i.e., if HDB1 is 20 ticks -// to the right of the ALDL and PWIDTH is 4, then start writing the LBUF starting at -// backbuffer + 5 pixels). - -// 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... -// Same with the width... [Width is pretty much virtualized now.] - -// Now that that the width is virtualized, let's virtualize the height. :-) uint32_t TOMGetVideoModeHeight(void) { -// uint16_t vmode = GET16(tomRam8, VMODE); -// uint16_t vbe = GET16(tomRam8, VBE); -// uint16_t vbb = GET16(tomRam8, VBB); -// uint16_t vdb = GET16(tomRam8, VDB); -// uint16_t vde = GET16(tomRam8, VDE); -// uint16_t vp = GET16(tomRam8, VP); - -/* if (vde == 0xFFFF) - vde = vbb;//*/ - -// return 227;//WAS:(vde/*-vdb*/) >> 1; - // The video mode height probably works this way: - // VC counts from 0 to VP. VDB starts the OP. Either when - // VDE is reached or VP, the OP is stopped. Let's try it... - // Also note that we're conveniently ignoring interlaced display modes...! -// return ((vde > vp ? vp : vde) - vdb) >> 1; -// return ((vde > vbb ? vbb : vde) - vdb) >> 1; -//Let's try from the Vertical Blank interval... -//Seems to work OK! -// return (vbb - vbe) >> 1; // Again, doesn't take interlacing into account... -// This of course doesn't take interlacing into account. But I haven't seen any -// Jaguar software that takes advantage of it either... -//Also, doesn't reflect PAL Jaguar either... !!! FIX !!! [DONE] -// return 240; // Set virtual screen height to 240 lines... + // Set virtual screen height to 240 (NTSC) or 256 (PAL) lines... return (vjs.hardwareTypeNTSC ? 240 : 256); }