]> Shamusworld >> Repos - virtualjaguar/commitdiff
Added stricter TOM memory checking.
authorShamus Hammons <jlhamm@acm.org>
Wed, 13 Jul 2011 17:05:21 +0000 (17:05 +0000)
committerShamus Hammons <jlhamm@acm.org>
Wed, 13 Jul 2011 17:05:21 +0000 (17:05 +0000)
src/blitter.cpp
src/file.cpp
src/gui/filepicker.cpp
src/jaguar.cpp
src/tom.cpp

index 3d4207d42f8d2c31e093e9eced5fffefebb2c9ac..3db442f3824dabd51d8034694d9ac3fc11ba82fd 100644 (file)
@@ -31,6 +31,8 @@
 
 // Various conditional compilation goodies...
 
+//#define LOG_BLITS
+
 //#define USE_ORIGINAL_BLITTER
 //#define USE_MIDSUMMER_BLITTER
 #define USE_MIDSUMMER_BLITTER_MKII
@@ -1825,9 +1827,9 @@ void LogBlit(void)
        WriteLog("  UPDA2    = %s\n", (UPDA2 ? "1" : "0"));
        WriteLog("  DSTA2    = %s\n", (DSTA2 ? "1" : "0"));
        WriteLog("  ZOP      = %s %s %s\n", (Z_OP_INF ? "<" : ""), (Z_OP_EQU ? "=" : ""), (Z_OP_SUP ? ">" : ""));
-       WriteLog("--LFUFUNC  = %s\n", opStr[(cmd >> 21) & 0x0F]);
+       WriteLog("+-LFUFUNC  = %s\n", opStr[(cmd >> 21) & 0x0F]);
        WriteLog("| PATDSEL  = %s (PD=%08X%08X)\n", (PATDSEL ? "1" : "0"), REG(PATTERNDATA), REG(PATTERNDATA + 4));
-       WriteLog("--ADDDSEL  = %s\n", (ADDDSEL ? "1" : "0"));
+       WriteLog("+-ADDDSEL  = %s\n", (ADDDSEL ? "1" : "0"));
        WriteLog("  CMPDST   = %s\n", (CMPDST ? "1" : "0"));
        WriteLog("  BCOMPEN  = %s\n", (BCOMPEN ? "1" : "0"));
        WriteLog("  DCOMPEN  = %s\n", (DCOMPEN ? "1" : "0"));
@@ -1854,6 +1856,9 @@ void LogBlit(void)
 
 void BlitterMidsummer(uint32 cmd)
 {
+#ifdef LOG_BLITS
+       LogBlit();
+#endif
 uint32 outer_loop, inner_loop, a1_addr, a2_addr;
 int32 a1_x, a1_y, a2_x, a2_y, a1_width, a2_width;
 uint8 a1_phrase_mode, a2_phrase_mode;
@@ -2672,6 +2677,9 @@ bool logBlit = false;
 
 void BlitterMidsummer2(void)
 {
+#ifdef LOG_BLITS
+       LogBlit();
+#endif
        // Here's what the specs say the state machine does. Note that this can probably be
        // greatly simplified (also, it's different from what John has in his Oberon docs):
 //Will remove stuff that isn't in Jaguar I once fully described (stuff like texture won't
index 78b4233c6eb53cda59df23bdfabd8e06be021915..ac39edead80ac15229f3ae7280e2a64798df4ebd 100644 (file)
@@ -483,7 +483,9 @@ uint32 GetFileFromZIP(const char * zipFile, FileType type, uint8 * &buffer)
                        WriteLog("FILE: Found image file '%s'.\n", ze->name);
                }
 
-               if ((type == FT_SOFTWARE) && (CheckExtension(ze->name, ".j64") || CheckExtension(ze->name, ".rom") || CheckExtension(ze->name, ".abs") || CheckExtension(ze->name, ".cof")))
+               if ((type == FT_SOFTWARE) && (CheckExtension(ze->name, ".j64")
+                       || CheckExtension(ze->name, ".rom") || CheckExtension(ze->name, ".abs")
+                       || CheckExtension(ze->name, ".cof") || CheckExtension(ze->name, ".jag")))
                {
                        found = true;
                        WriteLog("FILE: Found software file '%s'.\n", ze->name);
@@ -529,17 +531,7 @@ uint32 GetFileFromZIP(const char * zipFile, FileType type, uint8 * &buffer)
 //
 uint32 ParseFileType(uint8 header1, uint8 header2, uint32 size)
 {
-       // If the file size is divisible by 1M, we probably have an regular ROM.
-       // We can also check our CRC32 against the internal ROM database to be sure.
-       if ((size % 1048576) == 0)
-               return JST_ROM;
-
-       // If the file size + 8192 bytes is divisible by 1M, we probably have an
-       // Alpine format ROM.
-       if (((size + 8192) % 1048576) == 0)
-               return JST_ALPINE;
-
-       // So much for low hanging fruit. Now try some other types.
+       // Check headers first...
 
        // ABS/COFF type 1
        if (header1 == 0x60 && header2 == 0x1B)
@@ -553,6 +545,18 @@ uint32 ParseFileType(uint8 header1, uint8 header2, uint32 size)
        if (header1 == 0x60 && header2 == 0x1A)
                return JST_JAGSERVER;
 
+       // And if that fails, try file sizes...
+
+       // If the file size is divisible by 1M, we probably have an regular ROM.
+       // We can also check our CRC32 against the internal ROM database to be sure.
+       if ((size % 1048576) == 0)
+               return JST_ROM;
+
+       // If the file size + 8192 bytes is divisible by 1M, we probably have an
+       // Alpine format ROM.
+       if (((size + 8192) % 1048576) == 0)
+               return JST_ALPINE;
+
        // Headerless crap
        return JST_NONE;
 }
index e01f365bb2d7bb8da210dc4b81a6a1eedec7decd..a1694def2d6813cd19d915e07a235e4ae360e495 100644 (file)
@@ -420,7 +420,7 @@ void FilePickerWindow::UpdateSelection(const QModelIndex & current, const QModel
                else
                        fileTypeString = QString(tr("%1MB Alpine ROM"));
 
-               fileTypeString = fileTypeString.arg(fileSize / 1048576);
+               fileTypeString = fileTypeString.arg((fileSize + 8192) / 1048576);
        }
        else if (haveUnknown && (fileType == JST_ABS_TYPE1 || fileType == JST_ABS_TYPE2))
                fileTypeString = QString(tr("ABS/COF Executable (%1 bytes)")).arg(fileSize);
index 3ae824cbd7ad331fb61e83138e8acd51c78cf472..9cdade375c5f104a89496d91217c8f95c9c017db 100644 (file)
@@ -1521,6 +1521,9 @@ void JaguarReset(void)
        else
                SET32(jaguarMainRAM, 4, jaguarRunAddress);
 
+       if (vjs.useJaguarBIOS && !(biosAvailable & (BIOS_NORMAL | BIOS_STUB1 | BIOS_STUB2)))
+               WriteLog("Jaguar: Requested BIOS, but none available.\n");
+
 //     WriteLog("jaguar_reset():\n");
        TOMReset();
        JERRYReset();
@@ -1613,7 +1616,7 @@ void JaguarDone(void)
        WriteLog("\n");//*/
 
 //     WriteLog("Jaguar: CD BIOS version %04X\n", JaguarReadWord(0x3004));
-       WriteLog("Jaguar: Interrupt enable = %02X\n", TOMReadByte(0xF000E1) & 0x1F);
+       WriteLog("Jaguar: Interrupt enable = %02X\n", TOMReadByte(0xF000E1, JAGUAR) & 0x1F);
        WriteLog("Jaguar: VBL interrupt is %s\n", ((TOMIRQEnabled(IRQ_VBLANK)) && (JaguarInterruptHandlerIsValid(64))) ? "enabled" : "disabled");
        M68K_show_context();
 //#endif
@@ -1630,18 +1633,18 @@ void JaguarDone(void)
 //
 void JaguarExecute(uint32 * backbuffer, bool render)
 {
-       uint16 vp = TOMReadWord(0xF0003E) + 1;
-       uint16 vi = TOMReadWord(0xF0004E);
+       uint16 vp = TOMReadWord(0xF0003E, JAGUAR) + 1;
+       uint16 vi = TOMReadWord(0xF0004E, JAGUAR);
 //Using WO registers is OK, since we're the ones controlling access--there's nothing wrong here! ;-)
 //Though we shouldn't be able to do it using TOMReadWord... !!! FIX !!!
 
-//     uint16 vdb = TOMReadWord(0xF00046);
+//     uint16 vdb = TOMReadWord(0xF00046, JAGUAR);
 //Note: This is the *definite* end of the display, though VDE *might* be less than this...
-//     uint16 vbb = TOMReadWord(0xF00040);
+//     uint16 vbb = TOMReadWord(0xF00040, JAGUAR);
 //It seems that they mean it when they say that VDE is the end of object processing.
 //However, we need to be able to tell the OP (or TOM) that we've reached the end of the
 //buffer and not to write any more pixels... !!! FIX !!!
-//     uint16 vde = TOMReadWord(0xF00048);
+//     uint16 vde = TOMReadWord(0xF00048, JAGUAR);
 
        uint16 refreshRate = (vjs.hardwareTypeNTSC ? 60 : 50);
        uint32 m68kClockRate = (vjs.hardwareTypeNTSC ? M68K_CLOCK_RATE_NTSC : M68K_CLOCK_RATE_PAL);
@@ -1661,9 +1664,9 @@ if (effect_start)
        for(uint16 i=0; i<vp; i++)
        {
                // Increment the horizontal count (why? RNG? Besides which, this is *NOT* cycle accurate!)
-               TOMWriteWord(0xF00004, (TOMReadWord(0xF00004) + 1) & 0x7FF);
+               TOMWriteWord(0xF00004, (TOMReadWord(0xF00004, JAGUAR) + 1) & 0x7FF, JAGUAR);
 
-               TOMWriteWord(0xF00006, i);                                      // Write the VC
+               TOMWriteWord(0xF00006, i, JAGUAR);                      // Write the VC
 
 //             if (i == vi)                                                            // Time for Vertical Interrupt?
 //Not sure if this is correct...
@@ -1776,17 +1779,17 @@ void JaguarExecuteNew(void)
 
 void ScanlineCallback(void)
 {
-       uint16 vc = TOMReadWord(0xF00006);
-       uint16 vp = TOMReadWord(0xF0003E) + 1;
-       uint16 vi = TOMReadWord(0xF0004E);
-//     uint16 vbb = TOMReadWord(0xF00040);
+       uint16 vc = TOMReadWord(0xF00006, JAGUAR);
+       uint16 vp = TOMReadWord(0xF0003E, JAGUAR) + 1;
+       uint16 vi = TOMReadWord(0xF0004E, JAGUAR);
+//     uint16 vbb = TOMReadWord(0xF00040, JAGUAR);
        vc++;
 
        if (vc >= vp)
                vc = 0;
 
 //WriteLog("SLC: Currently on line %u (VP=%u)...\n", vc, vp);
-       TOMWriteWord(0xF00006, vc);
+       TOMWriteWord(0xF00006, vc, JAGUAR);
 
 //This is a crappy kludge, but maybe it'll work for now...
 //Maybe it's not so bad, since the IRQ happens on a scanline boundary...
@@ -1865,17 +1868,17 @@ void JaguarExecuteNew(void)
 
 void ScanlineCallback(void)
 {
-       uint16 vc = TOMReadWord(0xF00006);
-       uint16 vp = TOMReadWord(0xF0003E) + 1;
-       uint16 vi = TOMReadWord(0xF0004E);
-//     uint16 vbb = TOMReadWord(0xF00040);
+       uint16 vc = TOMReadWord(0xF00006, JAGUAR);
+       uint16 vp = TOMReadWord(0xF0003E, JAGUAR) + 1;
+       uint16 vi = TOMReadWord(0xF0004E, JAGUAR);
+//     uint16 vbb = TOMReadWord(0xF00040, JAGUAR);
        vc++;
 
        if (vc >= vp)
                vc = 0;
 
 //WriteLog("SLC: Currently on line %u (VP=%u)...\n", vc, vp);
-       TOMWriteWord(0xF00006, vc);
+       TOMWriteWord(0xF00006, vc, JAGUAR);
 
 //This is a crappy kludge, but maybe it'll work for now...
 //Maybe it's not so bad, since the IRQ happens on a scanline boundary...
index 3f56c8fba1b87961261d75e70dde24dbddb38c44..f9054f6769067aa6fcd9796409d640fdcb570a8d 100644 (file)
@@ -1098,7 +1098,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))
@@ -1129,7 +1129,7 @@ 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]);
@@ -1177,17 +1177,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))
@@ -1249,12 +1265,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)
@@ -1334,8 +1366,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);
@@ -1367,6 +1400,11 @@ if (offset == VMODE)
        // 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();
@@ -1381,6 +1419,7 @@ if (offset == VMODE)
 //                             ResizeScreen(tomWidth, tomHeight);
                }
        }
+#endif
 }
 
 int TOMIRQEnabled(int irq)