]> Shamusworld >> Repos - virtualjaguar/commitdiff
Changes to support new video subsystem
authorShamus Hammons <jlhamm@acm.org>
Tue, 2 Sep 2003 18:06:39 +0000 (18:06 +0000)
committerShamus Hammons <jlhamm@acm.org>
Tue, 2 Sep 2003 18:06:39 +0000 (18:06 +0000)
src/gui.cpp
src/include/gui.h
src/include/jaguar.h
src/jaguar.cpp
src/joystick.cpp
src/tom.cpp

index b1ffb370a3bc7eaee05c4ae27598c0d6e708c704..e1bf5c1e15c450344d0d7c532a65f75b8a8f905d 100644 (file)
@@ -5,17 +5,20 @@
 // by James L. Hammons
 //
 
-#include <string.h>
 #include <dirent.h>
 #include <SDL.h>
+#include <string>
+#include <vector>
+#include <algorithm>
 #include "types.h"
 #include "tom.h"
+#include "video.h"
 #include "font1.h"
 #include "gui.h"
 
-// Private function prototypes
+using namespace std;                                                           // For STL stuff
 
-uint32 CountROMFiles(char * path);
+// Private function prototypes
 
 
 void InitGUI(void)
@@ -26,34 +29,10 @@ void GUIDone(void)
 {
 }
 
-//
-// Render the backbuffer to the primary screen surface
-//
-void BlitBackbuffer(void)
-{
-       extern SDL_Surface * surface, * mainSurface;
-       extern int16 * backbuffer;
-
-       if (SDL_MUSTLOCK(surface))
-               while (SDL_LockSurface(surface) < 0)
-                       SDL_Delay(10);
-
-       memcpy(surface->pixels, backbuffer, tom_getVideoModeWidth() * tom_getVideoModeHeight() * 2);
-
-       if (SDL_MUSTLOCK(surface))
-               SDL_UnlockSurface(surface);
-
-       SDL_Rect srcrect, dstrect;
-       srcrect.x = srcrect.y = 0, srcrect.w = surface->w, srcrect.h = surface->h;
-       dstrect.x = dstrect.y = 0, dstrect.w = surface->w, dstrect.h = surface->h;
-       SDL_BlitSurface(surface, &srcrect, mainSurface, &dstrect);
-    SDL_Flip(mainSurface);      
-}
-
 //
 // Draw text at the given x/y coordinates. Can invert text as well.
 //
-void DrawText(int16 * screen, uint32 x, uint32 y, bool invert, const char * text, ...)
+void DrawString(int16 * screen, uint32 x, uint32 y, bool invert, const char * text, ...)
 {
        char string[4096];
        va_list arg;
@@ -62,7 +41,7 @@ void DrawText(int16 * screen, uint32 x, uint32 y, bool invert, const char * text
        vsprintf(string, text, arg);
        va_end(arg);
 
-       uint32 pitch = TOMGetSDLScreenPitch() / 2;              // Returns pitch in bytes but we need words...
+       uint32 pitch = GetSDLScreenPitch() / 2;                 // Returns pitch in bytes but we need words...
        uint32 length = strlen(string), address = x + (y * pitch);
 
        for(uint32 i=0; i<length; i++)
@@ -86,60 +65,23 @@ void DrawText(int16 * screen, uint32 x, uint32 y, bool invert, const char * text
 //
 // Very very crude GUI file selector
 //
-#ifndef FILENAME_MAX
-#define FILENAME_MAX   2048
-#endif
 bool UserSelectFile(char * path, char * filename)
 {
        extern int16 * backbuffer;
-       uint32 numFiles = CountROMFiles(path);
+       vector<string> fileList;
 
-       if (numFiles == 0)
-               return false;
+       // Read in the candidate files from the directory pointed to by "path"
 
-       char * names = (char *)malloc(numFiles * FILENAME_MAX);
-
-       if (names == NULL)
-       {
-               WriteLog("Could not allocate memory for %u files!\nAborting!\n", numFiles);
-               return false;
-       }
-
-       int i = 0;
        DIR * dp = opendir(path);
        dirent * de;
 
        while ((de = readdir(dp)) != NULL)
        {
                char * ext = strrchr(de->d_name, '.');
+
                if (ext != NULL)
-               {
                        if (stricmp(ext, ".zip") == 0 || stricmp(ext, ".jag") == 0)
-                       {
-                               // Do a QnD insertion sort...
-                               // (Yeah, it's n^2/2 time, but there aren't that many items...)
-                               uint32 pos = 0;
-
-                               for(int k=0; k<i; k++)
-                               {
-                                       if (stricmp(&names[k * FILENAME_MAX], de->d_name) < 0)
-                                               pos++;
-                                       else
-                                               break;
-                               }
-
-                               uint32 blockSize = (i - pos) * FILENAME_MAX;
-
-                               if (blockSize)
-//This only works on Win32 for some reason...
-//                                     memcpy(&names[(pos + 1) * FILENAME_MAX], &names[pos * FILENAME_MAX], blockSize);
-                                       for(int k=blockSize-1; k>=0; k--)
-                                               names[((pos + 1) * FILENAME_MAX) + k] = names[(pos * FILENAME_MAX) + k];
-
-                               strcpy(&names[pos * FILENAME_MAX], de->d_name);
-                               i++;
-                       }
-               }
+                               fileList.push_back(string(de->d_name));
        }
 
        closedir(dp);
@@ -148,10 +90,12 @@ bool UserSelectFile(char * path, char * filename)
 
        uint32 cursor = 0, startFile = 0;
 
-       if (numFiles > 1)       // Only go GUI if more than one possibility!
+       if (fileList.size() > 1)        // Only go GUI if more than one possibility!
        {
+               sort(fileList.begin(), fileList.end());
+
                bool done = false;
-               uint32 limit = (numFiles > 24 ? 24 : numFiles);
+               uint32 limit = (fileList.size() > 24 ? 24 : fileList.size());
                SDL_Event event;
 
                while (!done)
@@ -164,14 +108,14 @@ bool UserSelectFile(char * path, char * filename)
                                for(uint32 i=0; i<limit; i++)
                                {
                                        bool invert = (cursor == i ? true : false);
-                                       char buf[41];
-                                       // Guarantee that we clip our strings to fit in the screen...
-                                       memcpy(buf, &names[(startFile + i) * FILENAME_MAX], 38);
-                                       buf[38] = 0;
-                                       DrawText(backbuffer, 0, i*8, invert, " %s ", buf);
+                                       // Clip our strings to guarantee that they fit on the screen...
+                                       string s = fileList[startFile + i];
+                                       if (s.length() > 38)
+                                               s[38] = 0;
+                                       DrawString(backbuffer, 0, i*8, invert, " %s ", s.c_str());
                                }
 
-                               BlitBackbuffer();
+                               RenderBackbuffer();
 
                                if (event.type == SDL_KEYDOWN)
                                {
@@ -183,7 +127,7 @@ bool UserSelectFile(char * path, char * filename)
                                                        cursor++;
                                                else                                            // Otherwise, scroll the window...
                                                {
-                                                       if (cursor + startFile != numFiles - 1)
+                                                       if (cursor + startFile != fileList.size() - 1)
                                                                startFile++;
                                                }
                                        }
@@ -214,9 +158,10 @@ bool UserSelectFile(char * path, char * filename)
                                        {
                                                // Advance cursor to filename with first letter pressed...
                                                uint8 which = (key - SDLK_a) + 65;      // Convert key to A-Z char
-                                               for(uint32 i=0; i<numFiles; i++)
+
+                                               for(uint32 i=0; i<fileList.size(); i++)
                                                {
-                                                       if ((names[i * FILENAME_MAX] & 0xDF) == which)
+                                                       if ((fileList[i][0] & 0xDF) == which)
                                                        {
                                                                cursor = i - startFile;
                                                                if (i > startFile + limit - 1)
@@ -235,42 +180,12 @@ bool UserSelectFile(char * path, char * filename)
        }
 
        strcpy(filename, path);
-       // Potential GPF here: If length of dir is zero, then this will cause a page fault!
-       if (path[strlen(path) - 1] != '/')
-               strcat(filename, "/");
-       strcat(filename, &names[(cursor + startFile) * FILENAME_MAX]);
-       free(names);
-
-       return true;
-}
-
-//
-// Count # of possible ROM files in the current directory
-//
-uint32 CountROMFiles(char * path)
-{
-       uint32 numFiles = 0;
-       DIR * dp = opendir(path);
 
-       if (dp == NULL)
-       {
-               WriteLog("VJ: Could not open directory \"%s\"!\nAborting!\n", path);
-               return 0;
-       }
-       else
-       {
-               dirent * de;
+       if (strlen(path) > 0)
+               if (path[strlen(path) - 1] != '/')
+                       strcat(filename, "/");
 
-               while ((de = readdir(dp)) != NULL)
-               {
-                       char * ext = strrchr(de->d_name, '.');
-                       if (ext != NULL)
-                               if (stricmp(ext, ".zip") == 0 || stricmp(ext, ".jag") == 0)
-                                       numFiles++;
-               }
+       strcat(filename, fileList[startFile + cursor].c_str());
 
-               closedir(dp);
-       }
-
-       return numFiles;
+       return true;
 }
index 9efd8a2b7df9e54d48973ce63fce12e996137969..3836adb301595e51db7d1d4e8ed4afb6487d1d64 100644 (file)
@@ -7,8 +7,15 @@
 #ifndef __GUI_H__
 #define __GUI_H__
 
-void BlitBackbuffer(void);
-void DrawText(int16 * screen, uint32 x, uint32 y, bool invert, const char * text, ...);
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void DrawString(int16 * screen, uint32 x, uint32 y, bool invert, const char * text, ...);
 bool UserSelectFile(char * path, char * filename);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif // __GUI_H__
index d3d69047fc198fbd6e1967be1e628dfd0163f7cd..4a1936f245b1f7b315e2170f2c097fb59a75b579 100644 (file)
@@ -1,6 +1,7 @@
 #ifndef __JAGUAR_H__
 #define __JAGUAR_H__
 
+#include <string.h>    // Why??? (for memset, etc... Lazy!) Dunno why, but this just strikes me as wrong...
 #include "types.h"
 #include "log.h"
 #include "version.h"
index 8e7ee328a5b03703d3ef4cea765d986b3394c51e..28578f54b0e5c91136fefe40319017744046f2bd 100644 (file)
@@ -9,6 +9,7 @@
 // 
 
 #include "jaguar.h"
+#include "video.h"
 //#include "m68kdasmAG.h"
 
 #define CPU_DEBUG
@@ -26,9 +27,9 @@ void M68K_show_context(void);
 
 // External variables
 
-extern bool hardwareTypeNTSC;                          // Set to false for PAL
+extern bool hardwareTypeNTSC;                                          // Set to false for PAL
 #ifdef CPU_DEBUG_MEMORY
-extern bool startMemLog;                                       // Set by "e" key
+extern bool startMemLog;                                                       // Set by "e" key
 extern int effect_start;
 extern int effect_start2, effect_start3, effect_start4, effect_start5, effect_start6;
 #endif
@@ -40,8 +41,8 @@ char * whoName[9] =
 
 // These values are overridden by command line switches...
 
-bool dsp_enabled = false;
-bool jaguar_use_bios = true;                           // Default is now to USE the BIOS
+extern bool dsp_enabled;
+extern bool jaguar_use_bios;                                           // Default is now to USE the BIOS
 uint32 jaguar_active_memory_dumps = 0;
 
 uint32 jaguar_mainRom_crc32;
@@ -63,6 +64,15 @@ uint32 returnAddr[4000], raPtr = 0xFFFFFFFF;
 void M68KInstructionHook(void)
 {
        uint32 m68kPC = m68k_get_reg(NULL, M68K_REG_PC);
+/*     if (m68kPC >= 0x807EC4 && m68kPC <= 0x807EDB)
+       {
+               static char buffer[2048];
+               m68k_disassemble(buffer, m68kPC, M68K_CPU_TYPE_68000);
+               WriteLog("%08X: %s", m68kPC, buffer);
+               WriteLog("\t\tA0=%08X, A1=%08X, D0=%08X, D1=%08X\n",
+                       m68k_get_reg(NULL, M68K_REG_A0), m68k_get_reg(NULL, M68K_REG_A1),
+                       m68k_get_reg(NULL, M68K_REG_D0), m68k_get_reg(NULL, M68K_REG_D1));
+       }//*/
 /*     if (m68kPC == 0x8D0E48 && effect_start5)
        {
                WriteLog("\nM68K: At collision detection code. Exiting!\n\n");
@@ -122,7 +132,7 @@ void M68KInstructionHook(void)
                M68K_show_context();
                log_done();
                exit(0);
-       }
+       }//*/
 }
 
 //
@@ -339,7 +349,12 @@ if (address == 0xF02110)
        else if ((address >= 0xF10000) && (address <= 0xF1FFFE))
                JERRYWriteWord(address, value, M68K);
        else
+       {
                jaguar_unknown_writeword(address, value, M68K);
+               WriteLog("\tA0=%08X, A1=%08X, D0=%08X, D1=%08X\n",
+                       m68k_get_reg(NULL, M68K_REG_A0), m68k_get_reg(NULL, M68K_REG_A1),
+                       m68k_get_reg(NULL, M68K_REG_D0), m68k_get_reg(NULL, M68K_REG_D1));
+       }
 }
 
 void m68k_write_memory_32(unsigned int address, unsigned int value)
@@ -398,6 +413,22 @@ void M68K_show_context(void)
 // Unknown read/write byte/word routines
 //
 
+// It's hard to believe that developers would be sloppy with their memory writes, yet in
+// some cases the developers screwed up royal. E.g., Club Drive has the following code:
+//
+// 807EC4: movea.l #$f1b000, A1
+// 807ECA: movea.l #$8129e0, A0
+// 807ED0: move.l  A0, D0
+// 807ED2: move.l  #$f1bb94, D1
+// 807ED8: sub.l   D0, D1
+// 807EDA: lsr.l   #2, D1
+// 807EDC: move.l  (A0)+, (A1)+
+// 807EDE: dbra    D1, 807edc
+//
+// The problem is at $807ED0--instead of putting A0 into D0, they really meant to put A1
+// in. This mistake causes it to try and overwrite approximately $700000 worth of address
+// space! (That is, unless the 68K causes a bus error...)
+
 void jaguar_unknown_writebyte(unsigned address, unsigned data, uint32 who/*=UNKNOWN*/)
 {
 #ifdef LOG_UNMAPPED_MEMORY_ACCESSES
@@ -566,34 +597,37 @@ void JaguarWriteByte(uint32 offset, uint8 data, uint32 who/*=UNKNOWN*/)
 void JaguarWriteWord(uint32 offset, uint16 data, uint32 who/*=UNKNOWN*/)
 {
 //TEMP--Mirror of F03000? Yes, but only 32-bit CPUs can do it (i.e., NOT the 68K!)
-//if (offset >= 0xF0B000 && offset <= 0xF0BFFF)
-//WriteLog("[JWW16] --> Possible GPU RAM mirror access! [%08X]", offset);
-//if ((offset >= 0x1FF020 && offset <= 0x1FF03F) || (offset >= 0x1FF820 && offset <= 0x1FF83F))
-//     WriteLog("JagWW: Writing %04X at %08X\n", data, offset);
+// PLUS, you would handle this in the GPU/DSP WroteLong code! Not here!
        offset &= 0xFFFFFF;
-       
+
        if (offset <= 0x3FFFFE)
        {
+if (offset == 0x670C)
+       WriteLog("Jaguar: %s writing to location $670C...\n", whoName[who]);
+
                jaguar_mainRam[(offset+0) & 0x3FFFFF] = (data>>8) & 0xFF;
                jaguar_mainRam[(offset+1) & 0x3FFFFF] = data & 0xFF;
                return;
        }
-       else if ((offset >= 0xDFFF00) && (offset <= 0xDFFFFE))
+       else if (offset >= 0xDFFF00 && offset <= 0xDFFFFE)
        {
                CDROMWriteWord(offset, data, who);
                return;
        }
-       else if ((offset >= 0xF00000) && (offset <= 0xF0FFFE))
+       else if (offset >= 0xF00000 && offset <= 0xF0FFFE)
        {
                TOMWriteWord(offset, data, who);
                return;
        }
-       else if ((offset >= 0xF10000) && (offset <= 0xF1FFFE))
+       else if (offset >= 0xF10000 && offset <= 0xF1FFFE)
        {
                JERRYWriteWord(offset, data, who);
                return;
        }
-    
+       // Don't bomb on attempts to write to ROM
+       else if (offset >= 0x800000 && offset <= 0xEFFFFF)
+               return;
+
        jaguar_unknown_writeword(offset, data, who);
 }
 
@@ -625,7 +659,8 @@ void jaguar_init(void)
        memory_malloc_secure((void **)&jaguar_mainRom, 0x600000, "Jaguar 68K CPU ROM");
        memset(jaguar_mainRam, 0x00, 0x400000);
 //     memset(jaguar_mainRom, 0xFF, 0x200000); // & set it to all Fs...
-       memset(jaguar_mainRom, 0x00, 0x200000); // & set it to all 0s...
+//     memset(jaguar_mainRom, 0x00, 0x200000); // & set it to all 0s...
+       memset(jaguar_mainRom, 0x01, 0x600000); // & set it to all 01s...
 
 //     cd_bios_boot("C:\\ftp\\jaguar\\cd\\Brain Dead 13.cdi");
 //     cd_bios_boot("C:\\ftp\\jaguar\\cd\\baldies.cdi");
@@ -708,10 +743,16 @@ void jaguar_done(void)
        jaguar_dasm(0x802B00, 500);
        WriteLog("\n");//*/
 
-/*     WriteLog("\n\nM68000 disassembly at $8099F8...\n");
+/*     WriteLog("\n\nM68000 disassembly at $809900 (look @ $8099F8)...\n");
        jaguar_dasm(0x809900, 500);
        WriteLog("\n");//*/
 //8099F8
+/*     WriteLog("\n\nDump of $8093C8:\n\n");
+       for(int i=0x8093C8; i<0x809900; i+=4)
+               WriteLog("%06X: %08X\n", i, JaguarReadLong(i));//*/
+/*     WriteLog("\n\nM68000 disassembly at $90006C...\n");
+       jaguar_dasm(0x90006C, 500);
+       WriteLog("\n");//*/
 
 //     WriteLog("Jaguar: CD BIOS version %04X\n", JaguarReadWord(0x3004));
        WriteLog("Jaguar: Interrupt enable = %02X\n", TOMReadByte(0xF000E1) & 0x1F);
@@ -829,7 +870,7 @@ if (effect_start)
                        if (!(i & 0x01))                                                // Execute OP only on even lines (non-interlaced only!)
                        {
                                tom_exec_scanline(backbuffer, i/2, render);     // i/2 is a kludge...
-                               backbuffer += TOMGetSDLScreenPitch() / 2;       // Convert bytes to words...
+                               backbuffer += GetSDLScreenPitch() / 2;  // Convert bytes to words...
                        }
                }
        }
index 89a0098afe470d067c8669af3043e31ea653866d..9b0f3c7075a5b3e09b634ce9c462d78a5f48aff1 100644 (file)
@@ -9,6 +9,7 @@
 #include <time.h>
 #include <SDL.h>
 #include "jaguar.h"
+#include "video.h"
 
 #define BUTTON_U               0
 #define BUTTON_D               1
@@ -35,7 +36,7 @@
 
 // Private function prototypes
 
-void main_screen_switch(void);
+//void main_screen_switch(void);
 
 // Global vars
 
@@ -58,28 +59,6 @@ int objectPtr = 0;
 bool startMemLog = false;
 
 
-void main_screen_switch(void)
-{
-       extern SDL_Surface * mainSurface;
-       extern Uint32 mainSurfaceFlags;
-       extern bool fullscreen;
-
-       fullscreen = !fullscreen;
-       mainSurfaceFlags &= ~SDL_FULLSCREEN;
-       if (fullscreen)
-               mainSurfaceFlags |= SDL_FULLSCREEN;
-
-       mainSurface = SDL_SetVideoMode(tom_width, tom_height, 16, mainSurfaceFlags);
-
-       if (mainSurface == NULL)
-       {
-               WriteLog("Joystick: SDL is unable to set the video mode: %s\n", SDL_GetError());
-               exit(1);
-       }
-
-       SDL_WM_SetCaption("Virtual Jaguar", "Virtual Jaguar");
-}
-
 void joystick_init(void)
 {
        joystick_reset();
@@ -100,7 +79,7 @@ void joystick_exec(void)
        iLeft = iRight = false;
 
        if ((keystate[SDLK_LALT] || keystate[SDLK_RALT]) & keystate[SDLK_RETURN])
-               main_screen_switch();
+               ToggleFullscreen();
 
        /* Added/Changed by SDLEMU (http://sdlemu.ngemu.com) */
 
index f634284a8dad4f99f59b1f910ce469a28aa4a1bf..c949c728609c86116f1d4397b1f1cad565b9fab4 100644 (file)
 //     F02298            W   xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx   B_Z0 - Z0
 //     ------------------------------------------------------------
 
-#include <SDL.h>
+//#include <SDL.h>
 #include "tom.h"
+#include "video.h"
 #include "gpu.h"
 #include "objectp.h"
 #include "cry2rgb.h"
 #define BG                     0x58
 #define INT1           0xE0
 
+// Arbitrary video cutoff values (i.e., first/last visible spots on a TV, in HC ticks)
+/*#define LEFT_VISIBLE_HC              208
+#define RIGHT_VISIBLE_HC       1528//*/
+#define LEFT_VISIBLE_HC                208
+#define RIGHT_VISIBLE_HC       1488
+
 //This can be defined in the makefile as well...
 //(It's easier to do it here, though...)
 //#define TOM_DEBUG
@@ -342,6 +349,102 @@ render_xxx_scanline_fn * scanline_render_stretch[]=
 render_xxx_scanline_fn * scanline_render[8];
 
 
+// Screen info for various games...
+/*
+Doom
+TOM: Horizontal Display End written by M68K: 1727
+TOM: Horizontal Display Begin 1 written by M68K: 123
+TOM: Vertical Display Begin written by M68K: 25
+TOM: Vertical Display End written by M68K: 2047
+TOM: Video Mode written by M68K: 0EC1. PWIDTH = 8, MODE = 16 BPP CRY, flags: BGEN (VC = 5)
+Also does PWIDTH = 4...
+Vertical resolution: 238 lines
+
+Rayman
+TOM: Horizontal Display End written by M68K: 1727
+TOM: Horizontal Display Begin 1 written by M68K: 123
+TOM: Vertical Display Begin written by M68K: 25
+TOM: Vertical Display End written by M68K: 2047
+TOM: Vertical Interrupt written by M68K: 507
+TOM: Video Mode written by M68K: 06C7. PWIDTH = 4, MODE = 16 BPP RGB, flags: BGEN (VC = 92)
+TOM: Horizontal Display Begin 1 written by M68K: 208
+TOM: Horizontal Display End written by M68K: 1670
+Display starts at 31, then 52!
+Vertical resolution: 238 lines
+
+Atari Karts
+TOM: Horizontal Display End written by M68K: 1727
+TOM: Horizontal Display Begin 1 written by M68K: 123
+TOM: Vertical Display Begin written by M68K: 25
+TOM: Vertical Display End written by M68K: 2047
+TOM: Video Mode written by GPU: 08C7. PWIDTH = 5, MODE = 16 BPP RGB, flags: BGEN (VC = 4)
+TOM: Video Mode written by GPU: 06C7. PWIDTH = 4, MODE = 16 BPP RGB, flags: BGEN (VC = 508)
+Display starts at 31 (PWIDTH = 4), 24 (PWIDTH = 5)
+
+Iron Soldier
+TOM: Vertical Interrupt written by M68K: 2047
+TOM: Video Mode written by M68K: 06C1. PWIDTH = 4, MODE = 16 BPP CRY, flags: BGEN (VC = 0)
+TOM: Horizontal Display End written by M68K: 1727
+TOM: Horizontal Display Begin 1 written by M68K: 123
+TOM: Vertical Display Begin written by M68K: 25
+TOM: Vertical Display End written by M68K: 2047
+TOM: Vertical Interrupt written by M68K: 507
+TOM: Video Mode written by M68K: 06C1. PWIDTH = 4, MODE = 16 BPP CRY, flags: BGEN (VC = 369)
+TOM: Video Mode written by M68K: 06C1. PWIDTH = 4, MODE = 16 BPP CRY, flags: BGEN (VC = 510)
+TOM: Video Mode written by M68K: 06C3. PWIDTH = 4, MODE = 24 BPP RGB, flags: BGEN (VC = 510)
+Display starts at 31
+Vertical resolution: 238 lines
+[Seems to be a problem between the horizontal positioning of the 16-bit CRY & 24-bit RGB]
+
+JagMania
+TOM: Horizontal Period written by M68K: 844 (+1*2 = 1690)
+TOM: Horizontal Blank Begin written by M68K: 1713
+TOM: Horizontal Blank End written by M68K: 125
+TOM: Horizontal Display End written by M68K: 1696
+TOM: Horizontal Display Begin 1 written by M68K: 166
+TOM: Vertical Period written by M68K: 523 (non-interlaced)
+TOM: Vertical Blank End written by M68K: 24
+TOM: Vertical Display Begin written by M68K: 46
+TOM: Vertical Display End written by M68K: 496
+TOM: Vertical Blank Begin written by M68K: 500
+TOM: Vertical Sync written by M68K: 517
+TOM: Vertical Interrupt written by M68K: 497
+TOM: Video Mode written by M68K: 04C1. PWIDTH = 3, MODE = 16 BPP CRY, flags: BGEN (VC = 270)
+Display starts at 55
+
+Double Dragon V
+TOM: Horizontal Display End written by M68K: 1727
+TOM: Horizontal Display Begin 1 written by M68K: 123
+TOM: Vertical Display Begin written by M68K: 25
+TOM: Vertical Display End written by M68K: 2047
+TOM: Vertical Interrupt written by M68K: 507
+TOM: Video Mode written by M68K: 06C7. PWIDTH = 4, MODE = 16 BPP RGB, flags: BGEN (VC = 9)
+
+Dino Dudes
+TOM: Horizontal Display End written by M68K: 1823
+TOM: Horizontal Display Begin 1 written by M68K: 45
+TOM: Vertical Display Begin written by M68K: 40
+TOM: Vertical Display End written by M68K: 2047
+TOM: Vertical Interrupt written by M68K: 491
+TOM: Video Mode written by M68K: 06C1. PWIDTH = 4, MODE = 16 BPP CRY, flags: BGEN (VC = 398)
+Display starts at 11 (123 - 45 = 78, 78 / 4 = 19 pixels to skip)
+Width is 417, so maybe width of 379 would be good (starting at 123, ending at 1639)
+Vertical resolution: 238 lines
+
+Flashback
+TOM: Horizontal Display End written by M68K: 1727
+TOM: Horizontal Display Begin 1 written by M68K: 188
+TOM: Vertical Display Begin written by M68K: 1
+TOM: Vertical Display End written by M68K: 2047
+TOM: Vertical Interrupt written by M68K: 483
+TOM: Video Mode written by M68K: 08C7. PWIDTH = 5, MODE = 16 BPP RGB, flags: BGEN (VC = 99)
+Width would be 303 with above scheme, but border width would be 13 pixels
+
+Trevor McFur
+Vertical resolution: 238 lines
+*/
+
+
 void tom_calc_cry_rgb_mix_lut(void)
 {
        memory_malloc_secure((void **)&tom_cry_rgb_mix_lut, 2 * 0x10000, "CRY/RGB mixed mode LUT");
@@ -421,6 +524,16 @@ void tom_render_16bpp_cry_rgb_mix_scanline(int16 * backbuffer)
        uint16 width = tom_width;
        uint8 * current_line_buffer = (uint8 *)&tom_ram_8[0x1800];
        
+       //New stuff--restrict our drawing...
+       uint8 pwidth = ((GET16(tom_ram_8, VMODE) & PWIDTH) >> 9) + 1;
+       //NOTE: May have to check HDB2 as well!
+       int16 startPos = GET16(tom_ram_8, HDB1) - LEFT_VISIBLE_HC;      // Get start position in HC ticks
+       startPos /= pwidth;
+       if (startPos < 0)
+               current_line_buffer += 2 * -startPos;
+       else
+               backbuffer += 2 * startPos, width -= startPos;
+
        while (width)
        {
                uint16 color = (*current_line_buffer++) << 8;
@@ -438,6 +551,16 @@ void tom_render_16bpp_cry_scanline(int16 * backbuffer)
        uint16 width = tom_width;
        uint8 * current_line_buffer = (uint8 *)&tom_ram_8[0x1800];
 
+       //New stuff--restrict our drawing...
+       uint8 pwidth = ((GET16(tom_ram_8, VMODE) & PWIDTH) >> 9) + 1;
+       //NOTE: May have to check HDB2 as well!
+       int16 startPos = GET16(tom_ram_8, HDB1) - LEFT_VISIBLE_HC;      // Get start position in HC ticks
+       startPos /= pwidth;
+       if (startPos < 0)
+               current_line_buffer += 2 * -startPos;
+       else
+               backbuffer += 2 * startPos, width -= startPos;
+
        while (width)
        {
                uint16 color = (*current_line_buffer++) << 8;
@@ -464,8 +587,20 @@ void tom_render_24bpp_scanline(int16 * backbuffer)
        uint16 width = tom_width;
        uint8 * current_line_buffer = (uint8 *)&tom_ram_8[0x1800];
        
+       //New stuff--restrict our drawing...
+       uint8 pwidth = ((GET16(tom_ram_8, VMODE) & PWIDTH) >> 9) + 1;
+       //NOTE: May have to check HDB2 as well!
+       int16 startPos = GET16(tom_ram_8, HDB1) - LEFT_VISIBLE_HC;      // Get start position in HC ticks
+       startPos /= pwidth;
+       if (startPos < 0)
+               current_line_buffer += 4 * -startPos;
+       else
+               backbuffer += 2 * startPos, width -= startPos;
+
        while (width)
        {
+               // This is NOT a good 8 -> 5 bit RGB conversion! (It saturates values below 8
+               // to zero and throws away almost *half* the color resolution!)
                uint16 green = (*current_line_buffer++) >> 3;
                uint16 red = (*current_line_buffer++) >> 3;
                current_line_buffer++;
@@ -502,6 +637,16 @@ void tom_render_16bpp_rgb_scanline(int16 * backbuffer)
        uint16 width = tom_width;
        uint8 * current_line_buffer = (uint8 *)&tom_ram_8[0x1800];
        
+       //New stuff--restrict our drawing...
+       uint8 pwidth = ((GET16(tom_ram_8, VMODE) & PWIDTH) >> 9) + 1;
+       //NOTE: May have to check HDB2 as well!
+       int16 startPos = GET16(tom_ram_8, HDB1) - LEFT_VISIBLE_HC;      // Get start position in HC ticks
+       startPos /= pwidth;
+       if (startPos < 0)
+               current_line_buffer += 2 * -startPos;
+       else
+               backbuffer += 2 * startPos, width -= startPos;
+
        while (width)
        {
                uint16 color = (*current_line_buffer++) << 8;
@@ -658,13 +803,6 @@ void tom_exec_scanline(int16 * backbuffer, int32 scanline, bool render)
        }
 }
 
-uint32 TOMGetSDLScreenPitch(void)
-{
-       extern SDL_Surface * surface;
-
-       return surface->pitch;
-}
-
 //
 // TOM initialization
 //
@@ -726,11 +864,18 @@ uint32 tom_getVideoModeWidth(void)
 //     return width[(GET16(tom_ram_8, VMODE) & PWIDTH) >> 9];
 
        // Now, we just calculate it...
-       uint16 hdb1 = GET16(tom_ram_8, HDB1), hde = GET16(tom_ram_8, HDE),
+/*     uint16 hdb1 = GET16(tom_ram_8, HDB1), hde = GET16(tom_ram_8, HDE),
                hbb = GET16(tom_ram_8, HBB), pwidth = ((GET16(tom_ram_8, 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);
+       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.
+       uint16 pwidth = ((GET16(tom_ram_8, VMODE) & PWIDTH) >> 9) + 1;
+//     return (RIGHT_VISIBLE_HC - LEFT_VISIBLE_HC) / pwidth;
+//Temporary, for testing Doom...
+       return (RIGHT_VISIBLE_HC - LEFT_VISIBLE_HC) / (pwidth == 8 ? 4 : pwidth);
 
 // More speculating...
 // According to the JTRM, the number of potential pixels across is given by the
@@ -746,12 +891,14 @@ uint32 tom_getVideoModeWidth(void)
 // 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...
+// Same with the width... [Width is pretty much virtualized now.]
 
 uint32 tom_getVideoModeHeight(void)
 {
@@ -1109,35 +1256,24 @@ 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(tom_ram_8, VC));
-/*#define   MODE               0x0006          // Line buffer to video generator mode
-#define   BGEN         0x0080          // Background enable (CRY & RGB16 only)
-#define   VARMOD       0x0100          // Mixed CRY/RGB16 mode
-#define   PWIDTH       0x0E00          // Pixel width in video clock cycles (value written + 1)*/
 
        // detect screen resolution changes
 //This may go away in the future, if we do the virtualized screen thing...
+//This may go away soon!
        if ((offset >= 0x28) && (offset <= 0x4F))
        {
                uint32 width = tom_getVideoModeWidth(), height = tom_getVideoModeHeight();
                tom_real_internal_width = width;
 
-//This looks like an attempt to render non-square pixels (though wrong...)
-/*             if (width == 640)
-               {
-                       memcpy(scanline_render, scanline_render_stretch, sizeof(scanline_render));
-                       width = 320;
-               }
-               else
-                       memcpy(scanline_render, scanline_render_normal, sizeof(scanline_render));//*/
-               
                if ((width != tom_width) || (height != tom_height))
                {
-                       extern SDL_Surface * surface, * mainSurface;
-                       extern Uint32 mainSurfaceFlags;
-                       static char window_title[256];
+//                     extern SDL_Surface * surface, * mainSurface;
+//                     extern Uint32 mainSurfaceFlags;
+//                     static char window_title[256];
                        
                        tom_width = width, tom_height = height;
-                       SDL_FreeSurface(surface);
+                       ResizeScreen(tom_width, tom_height);
+/*                     SDL_FreeSurface(surface);
                        surface = SDL_CreateRGBSurface(SDL_SWSURFACE, tom_width, tom_height,
                                16, 0x7C00, 0x03E0, 0x001F, 0);
                        if (surface == NULL)
@@ -1147,8 +1283,6 @@ if (offset == VMODE)
                        }
 
                        sprintf(window_title, "Virtual Jaguar (%i x %i)", (int)tom_width, (int)tom_height);
-//???Should we do this??? No!
-//     SDL_FreeSurface(mainSurface);
                        mainSurface = SDL_SetVideoMode(tom_width, tom_height, 16, mainSurfaceFlags);
 
                        if (mainSurface == NULL)
@@ -1157,7 +1291,7 @@ if (offset == VMODE)
                                exit(1);
                        }
 
-                       SDL_WM_SetCaption(window_title, window_title);
+                       SDL_WM_SetCaption(window_title, window_title);//*/
                }
        }
 }