X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fjaguar.cpp;h=f829892333e69db0c91109ae100b92c61b10b455;hb=a0fe543d62fa18a83c2c7d99d483ab5ea0f321b4;hp=e1b95aa4dbdedbf13daef539bd3d4c07cab46fd8;hpb=5d76d651dfc3aa0a2e810e6b6db2ae8a2e34c53e;p=virtualjaguar diff --git a/src/jaguar.cpp b/src/jaguar.cpp index e1b95aa..f829892 100644 --- a/src/jaguar.cpp +++ b/src/jaguar.cpp @@ -25,12 +25,14 @@ #include "dsp.h" #include "eeprom.h" #include "event.h" +#include "foooked.h" #include "gpu.h" #include "jerry.h" #include "joystick.h" #include "log.h" #include "m68000/m68kinterface.h" //#include "memory.h" +#include "memtrack.h" #include "mmu.h" #include "settings.h" #include "tom.h" @@ -44,6 +46,7 @@ #define CPU_DEBUG_MEMORY //#define LOG_CD_BIOS_CALLS #define CPU_DEBUG_TRACING +#define ALPINE_FUNCTIONS // Private function prototypes @@ -79,9 +82,31 @@ uint32_t returnAddr[4000], raPtr = 0xFFFFFFFF; #endif uint32_t pcQueue[0x400]; +uint32_t a0Queue[0x400]; +uint32_t a1Queue[0x400]; +uint32_t a2Queue[0x400]; +uint32_t a3Queue[0x400]; +uint32_t a4Queue[0x400]; +uint32_t a5Queue[0x400]; +uint32_t a6Queue[0x400]; +uint32_t a7Queue[0x400]; +uint32_t d0Queue[0x400]; +uint32_t d1Queue[0x400]; +uint32_t d2Queue[0x400]; +uint32_t d3Queue[0x400]; +uint32_t d4Queue[0x400]; +uint32_t d5Queue[0x400]; +uint32_t d6Queue[0x400]; +uint32_t d7Queue[0x400]; +uint32_t srQueue[0x400]; uint32_t pcQPtr = 0; bool startM68KTracing = false; +// Breakpoint on memory access vars (exported) +bool bpmActive = false; +uint32_t bpmAddress1; + + // // Callback function to detect illegal instructions // @@ -137,16 +162,36 @@ if (inRoutine) // For tracebacks... // Ideally, we'd save all the registers as well... - pcQueue[pcQPtr++] = m68kPC; + pcQueue[pcQPtr] = m68kPC; + a0Queue[pcQPtr] = m68k_get_reg(NULL, M68K_REG_A0); + a1Queue[pcQPtr] = m68k_get_reg(NULL, M68K_REG_A1); + a2Queue[pcQPtr] = m68k_get_reg(NULL, M68K_REG_A2); + a3Queue[pcQPtr] = m68k_get_reg(NULL, M68K_REG_A3); + a4Queue[pcQPtr] = m68k_get_reg(NULL, M68K_REG_A4); + a5Queue[pcQPtr] = m68k_get_reg(NULL, M68K_REG_A5); + a6Queue[pcQPtr] = m68k_get_reg(NULL, M68K_REG_A6); + a7Queue[pcQPtr] = m68k_get_reg(NULL, M68K_REG_A7); + d0Queue[pcQPtr] = m68k_get_reg(NULL, M68K_REG_D0); + d1Queue[pcQPtr] = m68k_get_reg(NULL, M68K_REG_D1); + d2Queue[pcQPtr] = m68k_get_reg(NULL, M68K_REG_D2); + d3Queue[pcQPtr] = m68k_get_reg(NULL, M68K_REG_D3); + d4Queue[pcQPtr] = m68k_get_reg(NULL, M68K_REG_D4); + d5Queue[pcQPtr] = m68k_get_reg(NULL, M68K_REG_D5); + d6Queue[pcQPtr] = m68k_get_reg(NULL, M68K_REG_D6); + d7Queue[pcQPtr] = m68k_get_reg(NULL, M68K_REG_D7); + srQueue[pcQPtr] = m68k_get_reg(NULL, M68K_REG_SR); + pcQPtr++; pcQPtr &= 0x3FF; if (m68kPC & 0x01) // Oops! We're fetching an odd address! { - WriteLog("M68K: Attempted to execute from an odd adress!\n\nBacktrace:\n\n"); + WriteLog("M68K: Attempted to execute from an odd address!\n\nBacktrace:\n\n"); static char buffer[2048]; for(int i=0; i<0x400; i++) { +// WriteLog("[A2=%08X, D0=%08X]\n", a2Queue[(pcQPtr + i) & 0x3FF], d0Queue[(pcQPtr + i) & 0x3FF]); + WriteLog("[A0=%08X, A1=%08X, A2=%08X, A3=%08X, A4=%08X, A5=%08X, A6=%08X, A7=%08X, D0=%08X, D1=%08X, D2=%08X, D3=%08X, D4=%08X, D5=%08X, D6=%08X, D7=%08X, SR=%04X]\n", a0Queue[(pcQPtr + i) & 0x3FF], a1Queue[(pcQPtr + i) & 0x3FF], a2Queue[(pcQPtr + i) & 0x3FF], a3Queue[(pcQPtr + i) & 0x3FF], a4Queue[(pcQPtr + i) & 0x3FF], a5Queue[(pcQPtr + i) & 0x3FF], a6Queue[(pcQPtr + i) & 0x3FF], a7Queue[(pcQPtr + i) & 0x3FF], d0Queue[(pcQPtr + i) & 0x3FF], d1Queue[(pcQPtr + i) & 0x3FF], d2Queue[(pcQPtr + i) & 0x3FF], d3Queue[(pcQPtr + i) & 0x3FF], d4Queue[(pcQPtr + i) & 0x3FF], d5Queue[(pcQPtr + i) & 0x3FF], d6Queue[(pcQPtr + i) & 0x3FF], d7Queue[(pcQPtr + i) & 0x3FF], srQueue[(pcQPtr + i) & 0x3FF]); m68k_disassemble(buffer, pcQueue[(pcQPtr + i) & 0x3FF], 0);//M68K_CPU_TYPE_68000); WriteLog("\t%08X: %s\n", pcQueue[(pcQPtr + i) & 0x3FF], buffer); } @@ -824,27 +869,33 @@ WriteLog("JERRY: (68K int en/lat - Unhandled!) Tried to write $%02X to $%08X!\n" ; // Do nothing } + void WriteWord(uint32_t adddress, uint16_t word) { } + void WriteDWord(uint32_t adddress, uint32_t dword) { } + uint8_t ReadByte(uint32_t adddress) { } + uint16_t ReadWord(uint32_t adddress) { } + uint32_t ReadDWord(uint32_t adddress) { } #endif + void ShowM68KContext(void) { printf("\t68K PC=%06X\n", m68k_get_reg(NULL, M68K_REG_PC)); @@ -878,6 +929,7 @@ void ShowM68KContext(void) while (disPC < (currpc + 10)); } + // // Custom UAE 68000 read/write/IRQ functions // @@ -954,10 +1006,12 @@ int irq_ack_handler(int level) // IPL1 is connected to INTL on TOM (OUT to 68K) // IPL0-2 are also tied to Vcc via 4.7K resistors! // (DINT on TOM goes into DINT on JERRY (IN Tom from Jerry)) - // There doesn't seem to be any other path to IPL0 or 2 on the schematic, which means - // that *all* IRQs to the 68K are routed thru TOM at level 2. Which means they're all maskable. + // There doesn't seem to be any other path to IPL0 or 2 on the schematic, + // which means that *all* IRQs to the 68K are routed thru TOM at level 2. + // Which means they're all maskable. - // The GPU/DSP/etc are probably *not* issuing an NMI, but it seems to work OK... + // The GPU/DSP/etc are probably *not* issuing an NMI, but it seems to work + // OK... // They aren't, and this causes problems with a, err, specific ROM. :-D if (level == 2) @@ -969,10 +1023,17 @@ int irq_ack_handler(int level) return M68K_INT_ACK_AUTOVECTOR; } + //#define USE_NEW_MMU unsigned int m68k_read_memory_8(unsigned int address) { +#ifdef ALPINE_FUNCTIONS + // Check if breakpoint on memory is active, and deal with it + if (bpmActive && address == bpmAddress1) + M68KDebugHalt(); +#endif + // Musashi does this automagically for you, UAE core does not :-P address &= 0x00FFFFFF; #ifdef CPU_DEBUG_MEMORY @@ -1020,11 +1081,18 @@ unsigned int m68k_read_memory_8(unsigned int address) #endif } + void gpu_dump_disassembly(void); void gpu_dump_registers(void); unsigned int m68k_read_memory_16(unsigned int address) { +#ifdef ALPINE_FUNCTIONS + // Check if breakpoint on memory is active, and deal with it + if (bpmActive && address == bpmAddress1) + M68KDebugHalt(); +#endif + // Musashi does this automagically for you, UAE core does not :-P address &= 0x00FFFFFF; #ifdef CPU_DEBUG_MEMORY @@ -1096,7 +1164,16 @@ unsigned int m68k_read_memory_16(unsigned int address) retVal = GET16(jaguarMainRAM, address); // else if ((address >= 0x800000) && (address <= 0xDFFFFE)) else if ((address >= 0x800000) && (address <= 0xDFFEFE)) - retVal = (jaguarMainROM[address - 0x800000] << 8) | jaguarMainROM[address - 0x800000 + 1]; + { + // Memory Track reading... + if (((TOMGetMEMCON1() & 0x0006) == (2 << 1)) && (jaguarMainROMCRC32 == 0xFDF37F47)) + { + retVal = MTReadWord(address); + } + else + retVal = (jaguarMainROM[address - 0x800000] << 8) + | jaguarMainROM[address - 0x800000 + 1]; + } else if ((address >= 0xE00000) && (address <= 0xE3FFFE)) // retVal = (jaguarBootROM[address - 0xE00000] << 8) | jaguarBootROM[address - 0xE00000 + 1]; // retVal = (jaguarDevBootROM1[address - 0xE00000] << 8) | jaguarDevBootROM1[address - 0xE00000 + 1]; @@ -1124,8 +1201,15 @@ unsigned int m68k_read_memory_16(unsigned int address) #endif } + unsigned int m68k_read_memory_32(unsigned int address) { +#ifdef ALPINE_FUNCTIONS + // Check if breakpoint on memory is active, and deal with it + if (bpmActive && address == bpmAddress1) + M68KDebugHalt(); +#endif + // Musashi does this automagically for you, UAE core does not :-P address &= 0x00FFFFFF; //; So, it seems that it stores the returned DWORD at $51136 and $FB074. @@ -1134,14 +1218,34 @@ unsigned int m68k_read_memory_32(unsigned int address) //WriteLog("--> [RM32]\n"); #ifndef USE_NEW_MMU - return (m68k_read_memory_16(address) << 16) | m68k_read_memory_16(address + 2); + uint32_t retVal = 0; + + if ((address >= 0x800000) && (address <= 0xDFFEFE)) + { + // Memory Track reading... + if (((TOMGetMEMCON1() & 0x0006) == (2 << 1)) && (jaguarMainROMCRC32 == 0xFDF37F47)) + retVal = MTReadLong(address); + else + retVal = GET32(jaguarMainROM, address - 0x800000); + + return retVal; + } + + return (m68k_read_memory_16(address) << 16) | m68k_read_memory_16(address + 2); #else return MMURead32(address, M68K); #endif } + void m68k_write_memory_8(unsigned int address, unsigned int value) { +#ifdef ALPINE_FUNCTIONS + // Check if breakpoint on memory is active, and deal with it + if (bpmActive && address == bpmAddress1) + M68KDebugHalt(); +#endif + // Musashi does this automagically for you, UAE core does not :-P address &= 0x00FFFFFF; #ifdef CPU_DEBUG_MEMORY @@ -1190,8 +1294,15 @@ void m68k_write_memory_8(unsigned int address, unsigned int value) #endif } + void m68k_write_memory_16(unsigned int address, unsigned int value) { +#ifdef ALPINE_FUNCTIONS + // Check if breakpoint on memory is active, and deal with it + if (bpmActive && address == bpmAddress1) + M68KDebugHalt(); +#endif + // Musashi does this automagically for you, UAE core does not :-P address &= 0x00FFFFFF; #ifdef CPU_DEBUG_MEMORY @@ -1258,6 +1369,12 @@ if (address == 0xF02110) jaguar_mainRam[address + 1] = value & 0xFF;*/ SET16(jaguarMainRAM, address, value); } + // Memory Track device writes.... + else if ((address >= 0x800000) && (address <= 0x87FFFE)) + { + if (((TOMGetMEMCON1() & 0x0006) == (2 << 1)) && (jaguarMainROMCRC32 == 0xFDF37F47)) + MTWriteWord(address, value); + } else if ((address >= 0xDFFF00) && (address <= 0xDFFFFE)) CDROMWriteWord(address, value, M68K); else if ((address >= 0xF00000) && (address <= 0xF0FFFE)) @@ -1278,8 +1395,15 @@ if (address == 0xF02110) #endif } + void m68k_write_memory_32(unsigned int address, unsigned int value) { +#ifdef ALPINE_FUNCTIONS + // Check if breakpoint on memory is active, and deal with it + if (bpmActive && address == bpmAddress1) + M68KDebugHalt(); +#endif + // Musashi does this automagically for you, UAE core does not :-P address &= 0x00FFFFFF; /*if (address == 0x4E00) @@ -1318,12 +1442,14 @@ uint32_t JaguarGetHandler(uint32_t i) return JaguarReadLong(i * 4); } + bool JaguarInterruptHandlerIsValid(uint32_t i) // Debug use only... { uint32_t handler = JaguarGetHandler(i); return (handler && (handler != 0xFFFFFFFF) ? true : false); } + void M68K_show_context(void) { WriteLog("68K PC=%06X\n", m68k_get_reg(NULL, M68K_REG_PC)); @@ -1376,12 +1502,14 @@ 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: +// 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 @@ -1392,9 +1520,10 @@ void M68K_show_context(void) // 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...) +// 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_t who/*=UNKNOWN*/) { @@ -1410,6 +1539,7 @@ void jaguar_unknown_writebyte(unsigned address, unsigned data, uint32_t who/*=UN #endif } + void jaguar_unknown_writeword(unsigned address, unsigned data, uint32_t who/*=UNKNOWN*/) { #ifdef LOG_UNMAPPED_MEMORY_ACCESSES @@ -1424,6 +1554,7 @@ void jaguar_unknown_writeword(unsigned address, unsigned data, uint32_t who/*=UN #endif } + unsigned jaguar_unknown_readbyte(unsigned address, uint32_t who/*=UNKNOWN*/) { #ifdef LOG_UNMAPPED_MEMORY_ACCESSES @@ -1439,6 +1570,7 @@ unsigned jaguar_unknown_readbyte(unsigned address, uint32_t who/*=UNKNOWN*/) return 0xFF; } + unsigned jaguar_unknown_readword(unsigned address, uint32_t who/*=UNKNOWN*/) { #ifdef LOG_UNMAPPED_MEMORY_ACCESSES @@ -1454,6 +1586,7 @@ unsigned jaguar_unknown_readword(unsigned address, uint32_t who/*=UNKNOWN*/) return 0xFFFF; } + // // Disassemble M68K instructions at the given offset // @@ -1463,16 +1596,19 @@ unsigned int m68k_read_disassembler_8(unsigned int address) return m68k_read_memory_8(address); } + unsigned int m68k_read_disassembler_16(unsigned int address) { return m68k_read_memory_16(address); } + unsigned int m68k_read_disassembler_32(unsigned int address) { return m68k_read_memory_32(address); } + void JaguarDasm(uint32_t offset, uint32_t qt) { #ifdef CPU_DEBUG @@ -1494,6 +1630,7 @@ void JaguarDasm(uint32_t offset, uint32_t qt) #endif } + uint8_t JaguarReadByte(uint32_t offset, uint32_t who/*=UNKNOWN*/) { uint8_t data = 0x00; @@ -1520,6 +1657,7 @@ uint8_t JaguarReadByte(uint32_t offset, uint32_t who/*=UNKNOWN*/) return data; } + uint16_t JaguarReadWord(uint32_t offset, uint32_t who/*=UNKNOWN*/) { offset &= 0xFFFFFF; @@ -1549,8 +1687,13 @@ uint16_t JaguarReadWord(uint32_t offset, uint32_t who/*=UNKNOWN*/) return jaguar_unknown_readword(offset, who); } + void JaguarWriteByte(uint32_t offset, uint8_t data, uint32_t who/*=UNKNOWN*/) { +/* if ((offset & 0x1FFFFF) >= 0xE00 && (offset & 0x1FFFFF) < 0xE18) + { + WriteLog("JWB: Byte %02X written at %08X by %s\n", data, offset, whoName[who]); + }//*/ /* if (offset >= 0x4E00 && offset < 0x4E04) WriteLog("JWB: Byte %02X written at %08X by %s\n", data, offset, whoName[who]);//*/ //Need to check for writes in the range of $18FA70 + 8000... @@ -1585,9 +1728,15 @@ void JaguarWriteByte(uint32_t offset, uint8_t data, uint32_t who/*=UNKNOWN*/) jaguar_unknown_writebyte(offset, data, who); } + uint32_t starCount; void JaguarWriteWord(uint32_t offset, uint16_t data, uint32_t who/*=UNKNOWN*/) { +/* if ((offset & 0x1FFFFF) >= 0xE00 && (offset & 0x1FFFFF) < 0xE18) + { + WriteLog("JWW: Word %04X written at %08X by %s\n", data, offset, whoName[who]); + WriteLog(" GPU PC = $%06X\n", GPUReadLong(0xF02110, DEBUG)); + }//*/ /* if (offset >= 0x4E00 && offset < 0x4E04) WriteLog("JWW: Word %04X written at %08X by %s\n", data, offset, whoName[who]);//*/ /*if (offset == 0x0100)//64*4) @@ -1720,12 +1869,14 @@ if (offset == 0x11D31A + 0x48000 || offset == 0x11D31A) jaguar_unknown_writeword(offset, data, who); } + // We really should re-do this so that it does *real* 32-bit access... !!! FIX !!! uint32_t JaguarReadLong(uint32_t offset, uint32_t who/*=UNKNOWN*/) { return (JaguarReadWord(offset, who) << 16) | JaguarReadWord(offset+2, who); } + // We really should re-do this so that it does *real* 32-bit access... !!! FIX !!! void JaguarWriteLong(uint32_t offset, uint32_t data, uint32_t who/*=UNKNOWN*/) { @@ -1742,18 +1893,21 @@ void JaguarWriteLong(uint32_t offset, uint32_t data, uint32_t who/*=UNKNOWN*/) JaguarWriteWord(offset+2, data & 0xFFFF, who); } + void JaguarSetScreenBuffer(uint32_t * buffer) { // This is in TOM, but we set it here... screenBuffer = buffer; } + void JaguarSetScreenPitch(uint32_t pitch) { // This is in TOM, but we set it here... screenPitch = pitch; } + // // Jaguar console initialization // @@ -1777,13 +1931,12 @@ void JaguarInit(void) //NOTE: This *doesn't* fix FlipOut... //Or does it? Hmm... //Seems to want $01010101... Dunno why. Investigate! - memset(jaguarMainROM, 0x01, 0x600000); // & set it to all 01s... +// memset(jaguarMainROM, 0x01, 0x600000); // & set it to all 01s... // memset(jaguar_mainRom, 0xFF, 0x600000); // & set it to all Fs... lowerField = false; // Reset the lower field flag //temp, for crappy crap that sux memset(jaguarMainRAM + 0x804, 0xFF, 4); -// m68k_set_cpu_type(M68K_CPU_TYPE_68000); m68k_pulse_reset(); // Need to do this so UAE disasm doesn't segfault on exit GPUInit(); DSPInit(); @@ -1798,8 +1951,9 @@ void HalflineCallback(void); void RenderCallback(void); void JaguarReset(void) { + // Only problem with this approach: It wipes out RAM loaded files...! // Contents of local RAM are quasi-stable; we simulate this by randomizing RAM contents - for(uint32_t i=0; i<0x200000; i+=4) + for(uint32_t i=8; i<0x200000; i+=4) *((uint32_t *)(&jaguarMainRAM[i])) = rand(); // New timer base code stuffola... @@ -1927,12 +2081,6 @@ void JaguarDone(void) M68K_show_context(); //#endif -#if 0 // This is drawn already... - WriteLog("Jaguar: 68K AutoVector table:\n", JaguarReadWord(0x3004)); - for(uint32_t i=0x64; i<=0x7C; i+=4) - WriteLog(" #%u: %08X\n", (i-0x64)/4, JaguarReadLong(i)); -#endif - CDROMDone(); GPUDone(); DSPDone(); @@ -1991,7 +2139,7 @@ void DumpMainMemory(void) if (fp == NULL) return; - fwrite(jaguarMainRAM, 1, 0x400000, fp); + fwrite(jaguarMainRAM, 1, 0x200000, fp); fclose(fp); } @@ -2027,14 +2175,13 @@ void JaguarExecuteNew(void) } -#define USE_CORRECT_PAL_TIMINGS -// A lot of confusion comes from here... -// The thing to keep in mind is that the VC is advanced every HALF line, regardless -// of whether the display is interlaced or not. The only difference with an -// interlaced display is that the high bit of VC will be set when the lower -// field is being rendered. (NB: The high bit of VC is ALWAYS set on the lower field, -// regardless of whether it's in interlace mode or not. -// NB2: Seems it doens't always, not sure what the constraint is...) +// +// The thing to keep in mind is that the VC is advanced every HALF line, +// regardless of whether the display is interlaced or not. The only difference +// with an interlaced display is that the high bit of VC will be set when the +// lower field is being rendered. (NB: The high bit of VC is ALWAYS set on the +// lower field, regardless of whether it's in interlace mode or not. +// NB2: Seems it doesn't always, not sure what the constraint is...) // // Normally, TVs will render a full frame in 1/30s (NTSC) or 1/25s (PAL) by // rendering two fields that are slighty vertically offset from each other. @@ -2045,46 +2192,37 @@ void JaguarExecuteNew(void) // We execute a half frame in each timeslice (1/60s NTSC, 1/50s PAL). // Since the number of lines in a FULL frame is 525 for NTSC, 625 for PAL, // it will be half this number for a half frame. BUT, since we're counting -// HALF lines, we double this number and we're back at 525 for NTSC, 625 for PAL. +// HALF lines, we double this number and we're back at 525 for NTSC, 625 for +// PAL. // // Scanline times are 63.5555... μs in NTSC and 64 μs in PAL // Half line times are, naturally, half of this. :-P +// void HalflineCallback(void) { -//OK, this is hardwired to run in NTSC, and for who knows how long. -//Need to fix this so that it does a half-line in the correct amount of time -//and number of lines, depending on which mode we're in. [FIXED] uint16_t vc = TOMReadWord(0xF00006, JAGUAR); uint16_t vp = TOMReadWord(0xF0003E, JAGUAR) + 1; uint16_t vi = TOMReadWord(0xF0004E, JAGUAR); // uint16_t vbb = TOMReadWord(0xF00040, JAGUAR); vc++; -#ifdef USE_CORRECT_PAL_TIMINGS // Each # of lines is for a full frame == 1/30s (NTSC), 1/25s (PAL). // So we cut the number of half-lines in a frame in half. :-P uint16_t numHalfLines = ((vjs.hardwareTypeNTSC ? 525 : 625) * 2) / 2; if ((vc & 0x7FF) >= numHalfLines) -#else - if ((vc & 0x7FF) >= vp) -#endif { - vc = 0; -// lowerField = !lowerField; - - // If we're rendering the lower field, set the high bit (#12, counting - // from 1) of VC - if (lowerField) - vc = 0x0800; + lowerField = !lowerField; + // If we're rendering the lower field, set the high bit (#11, counting + // from 0) of VC + vc = (lowerField ? 0x0800 : 0x0000); } -//WriteLog("SLC: Currently on line %u (VP=%u)...\n", vc, vp); +//WriteLog("HLC: Currently on line %u (VP=%u)...\n", vc, vp); 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... - if ((vc & 0x7FF) == vi && (vc & 0x7FF) > 0 && TOMIRQEnabled(IRQ_VIDEO)) // Time for Vertical Interrupt? + // Time for Vertical Interrupt? + if ((vc & 0x7FF) == vi && (vc & 0x7FF) > 0 && TOMIRQEnabled(IRQ_VIDEO)) { // We don't have to worry about autovectors & whatnot because the Jaguar // tells you through its HW registers who sent the interrupt... @@ -2103,22 +2241,6 @@ void HalflineCallback(void) frameDone = true; }//*/ -#ifdef USE_CORRECT_PAL_TIMINGS SetCallbackTime(HalflineCallback, (vjs.hardwareTypeNTSC ? 31.777777777 : 32.0)); -#else -// SetCallbackTime(HalflineCallback, 63.5555); - SetCallbackTime(HalflineCallback, 31.77775); -#endif } - -// This isn't currently used, but maybe it should be... -/* -Nah, the scanline based code is good enough, and runs in 1 frame. The GUI -handles all the rest, so this isn't needed. :-P -*/ -void RenderCallback(void) -{ -// SetCallbackTime(RenderCallback, 33303.082); // # Scanlines * scanline time - SetCallbackTime(RenderCallback, 16651.541); // # Scanlines * scanline time -}