// Various conditional compilation goodies...
+//#define LOG_BLITS
+
//#define USE_ORIGINAL_BLITTER
//#define USE_MIDSUMMER_BLITTER
#define USE_MIDSUMMER_BLITTER_MKII
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"));
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;
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
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);
//
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)
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;
}
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);
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();
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
//
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);
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...
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...
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...
// 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))
//???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]);
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))
//
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)
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);
// 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();
// ResizeScreen(tomWidth, tomHeight);
}
}
+#endif
}
int TOMIRQEnabled(int irq)