X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fjaguar.cpp;h=98adae1bb8300ae86b4f851c3ceec7a14857f07e;hb=2f21d8ee63902b160acbaf4c26caaaa0e23ca62f;hp=f524242241769b5f0e3af7778c024fcc4763c28d;hpb=dd520b965a1e6531bd1d285494b223ab04c5368b;p=virtualjaguar diff --git a/src/jaguar.cpp b/src/jaguar.cpp index f524242..98adae1 100644 --- a/src/jaguar.cpp +++ b/src/jaguar.cpp @@ -5,30 +5,34 @@ // GCC/SDL port by Niels Wagenaar (Linux/WIN32) and Carwin Jones (BeOS) // Cleanups and endian wrongness amelioration by James L. Hammons // Note: Endian wrongness probably stems from the MAME origins of this emu and -// the braindead way in which MAME handles memory. :-) +// the braindead way in which MAME handled memory when this was written. :-) +// +// JLH = James L. Hammons +// +// WHO WHEN WHAT +// --- ---------- ----------------------------------------------------------- +// JLH 11/25/2009 Major rewrite of memory subsystem and handlers // #include "jaguar.h" #include #include "SDL_opengl.h" +#include "blitter.h" #include "cdrom.h" +#include "dac.h" #include "dsp.h" +#include "eeprom.h" #include "event.h" #include "gpu.h" -#include "gui.h" #include "jerry.h" #include "joystick.h" #include "log.h" #include "m68k.h" -#include "memory.h" +//#include "memory.h" +#include "mmu.h" #include "settings.h" #include "tom.h" -#include "video.h" -#include "blitter.h" -#include "jerry.h" -#include "dac.h" -#include "eeprom.h" #define CPU_DEBUG //Do this in makefile??? Yes! Could, but it's easier to define here... @@ -37,6 +41,7 @@ #define ABORT_ON_ILLEGAL_INSTRUCTIONS //#define ABORT_ON_OFFICIAL_ILLEGAL_INSTRUCTION #define CPU_DEBUG_MEMORY +//#define LOG_CD_BIOS_CALLS // Private function prototypes @@ -54,25 +59,14 @@ extern int effect_start; extern int effect_start2, effect_start3, effect_start4, effect_start5, effect_start6; #endif -// Memory debugging identifiers - -const char * whoName[9] = - { "Unknown", "Jaguar", "DSP", "GPU", "TOM", "JERRY", "M68K", "Blitter", "OP" }; - uint32 jaguar_active_memory_dumps = 0; uint32 jaguarMainROMCRC32, jaguarROMSize, jaguarRunAddress; -uint8 jaguarMainRAM[0x400000]; // 68K CPU RAM -uint8 jaguarMainROM[0x600000]; // 68K CPU ROM -uint8 jaguarBootROM[0x040000]; // 68K CPU BIOS ROM--uses only half of this! -uint8 jaguarCDBootROM[0x040000]; // 68K CPU CD BIOS ROM bool BIOSLoaded = false; bool CDBIOSLoaded = false; -uint8 cdRAM[0x100]; -uint8 tomRAM[0x4000]; -uint8 jerryRAM[0x10000]; +uint32 * backbuffer; #ifdef CPU_DEBUG_MEMORY uint8 writeMemMax[0x400000], writeMemMin[0x400000]; @@ -250,6 +244,8 @@ if (m68kPC == 0x802058) start = true; WriteLog("--> [Calling BusWrite2] D2: %08X\n", m68k_get_reg(NULL, M68K_REG_D2)); // m68k_set_reg(M68K_REG_D2, 0x12345678); }//*/ + +#ifdef LOG_CD_BIOS_CALLS /* CD_init:: -> $3000 BIOS_VER:: -> $3004 @@ -315,7 +311,8 @@ CD_switch:: -> $306C WriteLog("\t\tA0=%08X, A1=%08X, D0=%08X, D1=%08X, D2=%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), m68k_get_reg(NULL, M68K_REG_D2)); -//*/ +#endif + #ifdef ABORT_ON_ILLEGAL_INSTRUCTIONS if (!m68k_is_valid_instruction(m68k_read_memory_16(m68kPC), M68K_CPU_TYPE_68000)) { @@ -352,6 +349,33 @@ CD_switch:: -> $306C exit(0); }//*/ #endif + +#if 0 +//001A0110: move.w #$0, $F000E2.l ; Restore Blitter/GPU bus priorities +//001A015C: rte ; Return from the interrupt +static bool disassembleGo = false; + if (m68kPC == 0x1A0110) + { + static char buffer[2048]; + m68k_disassemble(buffer, m68kPC, M68K_CPU_TYPE_68000); + WriteLog("--> [M68K IRQ Routine start] %08X: %s", m68kPC, buffer); + WriteLog("\t\tA0=%08X, A1=%08X, D0=%08X(cmd), D1=%08X(# bytes), D2=%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), m68k_get_reg(NULL, M68K_REG_D2)); + disassembleGo = true; + } + else if (m68kPC == 0x1A015C) + WriteLog("--> [M68K IRQ Routine end]\n"); + + if (disassembleGo) + { + static char buffer[2048]; + m68k_disassemble(buffer, m68kPC, M68K_CPU_TYPE_68000); + WriteLog("%08X: %s", m68kPC, buffer); + WriteLog("\tD0=$%08X, D1=$%08X, D2=$%08X\n", + m68k_get_reg(NULL, M68K_REG_D0), m68k_get_reg(NULL, M68K_REG_D1), m68k_get_reg(NULL, M68K_REG_D2)); + } +#endif } #if 0 @@ -364,7 +388,7 @@ things that are entirely internal to those modules. This way we should be able t this crap which is currently scattered over Hell's Half Acre(tm). Also: We need to distinguish whether or not we need .b, .w, and .dw versions of everything, or if there -is a good way to collapse that shit. +is a good way to collapse that shit (look below for inspiration). Current method works, but is error prone. /************************************* * @@ -435,7 +459,7 @@ ADDRESS_MAP_END */ #endif -#define EXPERIMENTAL_MEMORY_HANDLING +//#define EXPERIMENTAL_MEMORY_HANDLING // Experimental memory mappage... // Dunno if this is a good approach or not, but it seems to make better // sense to have all this crap in one spot intstead of scattered all over @@ -443,6 +467,116 @@ ADDRESS_MAP_END #ifdef EXPERIMENTAL_MEMORY_HANDLING // Needed defines... #define NEW_TIMER_SYSTEM + +/* +uint8 jaguarMainRAM[0x400000]; // 68K CPU RAM +uint8 jaguarMainROM[0x600000]; // 68K CPU ROM +uint8 jaguarBootROM[0x040000]; // 68K CPU BIOS ROM--uses only half of this! +uint8 jaguarCDBootROM[0x040000]; // 68K CPU CD BIOS ROM +bool BIOSLoaded = false; +bool CDBIOSLoaded = false; + +uint8 cdRAM[0x100]; +uint8 tomRAM[0x4000]; +uint8 jerryRAM[0x10000]; +static uint16 eeprom_ram[64]; + +// NOTE: CD BIOS ROM is read from cartridge space @ $802000 (it's a cartridge, after all) +*/ + +enum MemType { MM_NOP = 0, MM_RAM, MM_ROM, MM_IO }; + +// M68K Memory map/handlers +uint32 { + { 0x000000, 0x3FFFFF, MM_RAM, jaguarMainRAM }, + { 0x800000, 0xDFFEFF, MM_ROM, jaguarMainROM }, +// Note that this is really memory mapped I/O region... +// { 0xDFFF00, 0xDFFFFF, MM_RAM, cdRAM }, + { 0xDFFF00, 0xDFFF03, MM_IO, cdBUTCH }, // base of Butch == interrupt control register, R/W + { 0xDFFF04, 0xDFFF07, MM_IO, cdDSCNTRL }, // DSA control register, R/W + { 0xDFFF0A, 0xDFFF0B, MM_IO, cdDS_DATA }, // DSA TX/RX data, R/W + { 0xDFFF10, 0xDFFF13, MM_IO, cdI2CNTRL }, // i2s bus control register, R/W + { 0xDFFF14, 0xDFFF17, MM_IO, cdSBCNTRL }, // CD subcode control register, R/W + { 0xDFFF18, 0xDFFF1B, MM_IO, cdSUBDATA }, // Subcode data register A + { 0xDFFF1C, 0xDFFF1F, MM_IO, cdSUBDATB }, // Subcode data register B + { 0xDFFF20, 0xDFFF23, MM_IO, cdSB_TIME }, // Subcode time and compare enable (D24) + { 0xDFFF24, 0xDFFF27, MM_IO, cdFIFO_DATA }, // i2s FIFO data + { 0xDFFF28, 0xDFFF2B, MM_IO, cdI2SDAT2 }, // i2s FIFO data (old) + { 0xDFFF2C, 0xDFFF2F, MM_IO, cdUNKNOWN }, // Seems to be some sort of I2S interface + + { 0xE00000, 0xE3FFFF, MM_ROM, jaguarBootROM }, + +// { 0xF00000, 0xF0FFFF, MM_IO, TOM_REGS_RW }, + { 0xF00050, 0xF00051, MM_IO, tomTimerPrescaler }, + { 0xF00052, 0xF00053, MM_IO, tomTimerDivider }, + { 0xF00400, 0xF005FF, MM_RAM, tomRAM }, // CLUT A&B: How to link these? Write to one writes to the other... + { 0xF00600, 0xF007FF, MM_RAM, tomRAM }, // Actually, this is a good approach--just make the reads the same as well + //What about LBUF writes??? + { 0xF02100, 0xF0211F, MM_IO, GPUWriteByte }, // GPU CONTROL + { 0xF02200, 0xF0229F, MM_IO, BlitterWriteByte }, // BLITTER + { 0xF03000, 0xF03FFF, MM_RAM, GPUWriteByte }, // GPU RAM + + { 0xF10000, 0xF1FFFF, MM_IO, JERRY_REGS_RW }, + +/* + EEPROM: + { 0xF14001, 0xF14001, MM_IO_RO, eepromFOO } + { 0xF14801, 0xF14801, MM_IO_WO, eepromBAR } + { 0xF15001, 0xF15001, MM_IO_RW, eepromBAZ } + + JOYSTICK: + { 0xF14000, 0xF14003, MM_IO, joystickFoo } + 0 = pad0/1 button values (4 bits each), RO(?) + 1 = pad0/1 index value (4 bits each), WO + 2 = unused, RO + 3 = NTSC/PAL, certain button states, RO + +JOYSTICK $F14000 Read/Write + 15.....8 7......0 +Read fedcba98 7654321q f-1 Signals J15 to J1 + q Cartridge EEPROM output data +Write exxxxxxm 76543210 e 1 = enable J7-J0 outputs + 0 = disable J7-J0 outputs + x don't care + m Audio mute + 0 = Audio muted (reset state) + 1 = Audio enabled + 7-4 J7-J4 outputs (port 2) + 3-0 J3-J0 outputs (port 1) +JOYBUTS $F14002 Read Only + 15.....8 7......0 +Read xxxxxxxx rrdv3210 x don't care + r Reserved + d Reserved + v 1 = NTSC Video hardware + 0 = PAL Video hardware + 3-2 Button inputs B3 & B2 (port 2) + 1-0 Button inputs B1 & B0 (port 1) + +J4 J5 J6 J7 Port 2 B2 B3 J12 J13 J14 J15 +J3 J2 J1 J0 Port 1 B0 B1 J8 J9 J10 J11 + 0 0 0 0 + 0 0 0 1 + 0 0 1 0 + 0 0 1 1 + 0 1 0 0 + 0 1 0 1 + 0 1 1 0 + 0 1 1 1 Row 3 C3 Option # 9 6 3 + 1 0 0 0 + 1 0 0 1 + 1 0 1 0 + 1 0 1 1 Row 2 C2 C 0 8 5 2 + 1 1 0 0 + 1 1 0 1 Row 1 C1 B * 7 4 1 + 1 1 1 0 Row 0 Pause A Up Down Left Right + 1 1 1 1 + +0 bit read in any position means that button is pressed. +C3 = C2 = 1 means std. Jag. cntrlr. or nothing attached. +*/ +}; + void WriteByte(uint32 address, uint8 byte, uint32 who/*=UNKNOWN*/) { // Not sure, but I think the system only has 24 address bits... @@ -673,21 +807,88 @@ uint32 ReadDWord(uint32 adddress) // Musashi 68000 read/write/IRQ functions // +#if 0 +IRQs: +=-=-= + + IPL Name Vector Control + ---------+---------------+---------------+--------------- + 2 VBLANK IRQ $100 INT1 bit #0 + 2 GPU IRQ $100 INT1 bit #1 + 2 HBLANK IRQ $100 INT1 bit #2 + 2 Timer IRQ $100 INT1 bit #3 + + Note: Both timer interrupts (JPIT && PIT) are on the same INT1 bit. + and are therefore indistinguishable. + + A typical way to install a LEVEL2 handler for the 68000 would be + something like this, you gotta supply "last_line" and "handler". + Note that the interrupt is auto vectored thru $100 (not $68) + + + V_AUTO = $100 + VI = $F004E + INT1 = $F00E0 + INT2 = $F00E2 + + IRQS_HANDLED=$909 ;; VBLANK and TIMER + + move.w #$2700,sr ;; no IRQs please + move.l #handler,V_AUTO ;; install our routine + + move.w #last_line,VI ;; scanline where IRQ should occur + ;; should be 'odd' BTW + move.w #IRQS_HANDLE&$FF,INT1 ;; enable VBLANK + TIMER + move.w #$2100,sr ;; enable IRQs on the 68K + ... + +handler: + move.w d0,-(a7) + move.w INT1,d0 + btst.b #0,d0 + bne.b .no_blank + + ... + +.no_blank: + btst.b #3,d0 + beq.b .no_timer + + ... + +.no_timer: + move.w #IRQS_HANDLED,INT1 ; clear latch, keep IRQ alive + move.w #0,INT2 ; let GPU run again + move.w (a7)+,d0 + rte + + As you can see, if you have multiple INT1 interrupts coming in, + you need to check the lower byte of INT1, to see which interrupt + happened. +#endif int irq_ack_handler(int level) { - int vector = M68K_INT_ACK_AUTOVECTOR; + // Tracing the IPL lines on the Jaguar schematic yields the following: + // 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 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. // 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 == 7) + if (level == 2) { - m68k_set_irq(0); // Clear the IRQ... - vector = 64; // Set user interrupt #0 + m68k_set_irq(0); // Clear the IRQ (NOTE: Without this, the BIOS fails)... + return 64; // Set user interrupt #0 } - return vector; + return M68K_INT_ACK_AUTOVECTOR; } +//#define USE_NEW_MMU + unsigned int m68k_read_memory_8(unsigned int address) { #ifdef CPU_DEBUG_MEMORY @@ -702,15 +903,16 @@ unsigned int m68k_read_memory_8(unsigned int address) /* if (address == 0x51136 || address == 0x51138 || address == 0xFB074 || address == 0xFB076 || address == 0x1AF05E) WriteLog("[RM8 PC=%08X] Addr: %08X, val: %02X\n", m68k_get_reg(NULL, M68K_REG_PC), address, jaguar_mainRam[address]);//*/ +#ifndef USE_NEW_MMU unsigned int retVal = 0; if ((address >= 0x000000) && (address <= 0x3FFFFF)) - retVal = jaguarMainRam[address]; + retVal = jaguarMainRAM[address]; // else if ((address >= 0x800000) && (address <= 0xDFFFFF)) else if ((address >= 0x800000) && (address <= 0xDFFEFF)) - retVal = jaguarMainRom[address - 0x800000]; + retVal = jaguarMainROM[address - 0x800000]; else if ((address >= 0xE00000) && (address <= 0xE3FFFF)) - retVal = jaguarBootRom[address - 0xE00000]; + retVal = jaguarBootROM[address - 0xE00000]; else if ((address >= 0xDFFF00) && (address <= 0xDFFFFF)) retVal = CDROMReadByte(address); else if ((address >= 0xF00000) && (address <= 0xF0FFFF)) @@ -725,6 +927,9 @@ unsigned int m68k_read_memory_8(unsigned int address) //if (address >= 0x8B5E4 && address <= 0x8B5E4 + 16) // WriteLog("M68K: Read byte $%02X at $%08X [PC=%08X]\n", retVal, address, m68k_get_reg(NULL, M68K_REG_PC)); return retVal; +#else + return MMURead8(address, M68K); +#endif } void gpu_dump_disassembly(void); @@ -792,16 +997,17 @@ unsigned int m68k_read_memory_16(unsigned int address) /* if (address == 0x51136 || address == 0x51138 || address == 0xFB074 || address == 0xFB076 || address == 0x1AF05E) WriteLog("[RM16 PC=%08X] Addr: %08X, val: %04X\n", m68k_get_reg(NULL, M68K_REG_PC), address, GET16(jaguar_mainRam, address));//*/ +#ifndef USE_NEW_MMU unsigned int retVal = 0; if ((address >= 0x000000) && (address <= 0x3FFFFE)) // retVal = (jaguar_mainRam[address] << 8) | jaguar_mainRam[address+1]; - retVal = GET16(jaguarMainRam, 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]; + 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 = (jaguarBootROM[address - 0xE00000] << 8) | jaguarBootROM[address - 0xE00000 + 1]; else if ((address >= 0xDFFF00) && (address <= 0xDFFFFE)) retVal = CDROMReadWord(address, M68K); else if ((address >= 0xF00000) && (address <= 0xF0FFFE)) @@ -820,6 +1026,9 @@ unsigned int m68k_read_memory_16(unsigned int address) //if (address >= 0x8B5E4 && address <= 0x8B5E4 + 16) // WriteLog("M68K: Read word $%04X at $%08X [PC=%08X]\n", retVal, address, m68k_get_reg(NULL, M68K_REG_PC)); return retVal; +#else + return MMURead16(address, M68K); +#endif } unsigned int m68k_read_memory_32(unsigned int address) @@ -829,7 +1038,11 @@ unsigned int m68k_read_memory_32(unsigned int address) WriteLog("[RM32 PC=%08X] Addr: %08X, val: %08X\n", m68k_get_reg(NULL, M68K_REG_PC), address, (m68k_read_memory_16(address) << 16) | m68k_read_memory_16(address + 2));//*/ //WriteLog("--> [RM32]\n"); +#ifndef USE_NEW_MMU 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) @@ -853,8 +1066,9 @@ void m68k_write_memory_8(unsigned int address, unsigned int value) if (address >= 0x18FA70 && address < (0x18FA70 + 8000)) WriteLog("M68K: Byte %02X written at %08X by 68K\n", value, address);//*/ +#ifndef USE_NEW_MMU if ((address >= 0x000000) && (address <= 0x3FFFFF)) - jaguarMainRam[address] = value; + jaguarMainRAM[address] = value; else if ((address >= 0xDFFF00) && (address <= 0xDFFFFF)) CDROMWriteByte(address, value, M68K); else if ((address >= 0xF00000) && (address <= 0xF0FFFF)) @@ -863,6 +1077,9 @@ void m68k_write_memory_8(unsigned int address, unsigned int value) JERRYWriteByte(address, value, M68K); else jaguar_unknown_writebyte(address, value, M68K); +#else + MMUWrite8(address, value, M68K); +#endif } void m68k_write_memory_16(unsigned int address, unsigned int value) @@ -910,11 +1127,12 @@ if (address == 0xF02110) || address == 0x1AF05E) WriteLog("[WM16 PC=%08X] Addr: %08X, val: %04X\n", m68k_get_reg(NULL, M68K_REG_PC), address, value);//*/ +#ifndef USE_NEW_MMU if ((address >= 0x000000) && (address <= 0x3FFFFE)) { /* jaguar_mainRam[address] = value >> 8; jaguar_mainRam[address + 1] = value & 0xFF;*/ - SET16(jaguarMainRam, address, value); + SET16(jaguarMainRAM, address, value); } else if ((address >= 0xDFFF00) && (address <= 0xDFFFFE)) CDROMWriteWord(address, value, M68K); @@ -931,6 +1149,9 @@ if (address == 0xF02110) m68k_get_reg(NULL, M68K_REG_D0), m68k_get_reg(NULL, M68K_REG_D1)); #endif } +#else + MMUWrite16(address, value, M68K); +#endif } void m68k_write_memory_32(unsigned int address, unsigned int value) @@ -948,8 +1169,12 @@ if (address == 0xF03214 && value == 0x88E30047) /* if (address == 0x51136 || address == 0xFB074) WriteLog("[WM32 PC=%08X] Addr: %08X, val: %02X\n", m68k_get_reg(NULL, M68K_REG_PC), address, value);//*/ +#ifndef USE_NEW_MMU m68k_write_memory_16(address, value >> 16); m68k_write_memory_16(address + 2, value & 0xFFFF); +#else + MMUWrite32(address, value, M68K); +#endif } @@ -985,16 +1210,24 @@ void M68K_show_context(void) if (TOMIRQEnabled(IRQ_VBLANK)) { - WriteLog("vblank int: enabled\n"); + WriteLog("video int: enabled\n"); JaguarDasm(JaguarGetHandler(64), 0x200); } else - WriteLog("vblank int: disabled\n"); + WriteLog("video int: disabled\n"); WriteLog("..................\n"); for(int i=0; i<256; i++) - WriteLog("handler %03i at $%08X\n", i, (unsigned int)JaguarGetHandler(i)); + { + WriteLog("handler %03i at ", i);//$%08X\n", i, (unsigned int)JaguarGetHandler(i)); + uint32 address = (uint32)JaguarGetHandler(i); + + if (address == 0) + WriteLog(".........\n"); + else + WriteLog("$%08X\n", address); + } } // @@ -1121,13 +1354,13 @@ uint8 JaguarReadByte(uint32 offset, uint32 who/*=UNKNOWN*/) offset &= 0xFFFFFF; if (offset < 0x400000) - data = jaguarMainRam[offset & 0x3FFFFF]; + data = jaguarMainRAM[offset & 0x3FFFFF]; else if ((offset >= 0x800000) && (offset < 0xC00000)) - data = jaguarMainRom[offset - 0x800000]; + data = jaguarMainROM[offset - 0x800000]; else if ((offset >= 0xDFFF00) && (offset <= 0xDFFFFF)) data = CDROMReadByte(offset, who); else if ((offset >= 0xE00000) && (offset < 0xE40000)) - data = jaguarBootRom[offset & 0x3FFFF]; + data = jaguarBootROM[offset & 0x3FFFF]; else if ((offset >= 0xF00000) && (offset < 0xF10000)) data = TOMReadByte(offset, who); else if ((offset >= 0xF10000) && (offset < 0xF20000)) @@ -1143,18 +1376,18 @@ uint16 JaguarReadWord(uint32 offset, uint32 who/*=UNKNOWN*/) offset &= 0xFFFFFF; if (offset <= 0x3FFFFE) { - return (jaguarMainRam[(offset+0) & 0x3FFFFF] << 8) | jaguarMainRam[(offset+1) & 0x3FFFFF]; + return (jaguarMainRAM[(offset+0) & 0x3FFFFF] << 8) | jaguarMainRAM[(offset+1) & 0x3FFFFF]; } else if ((offset >= 0x800000) && (offset <= 0xBFFFFE)) { offset -= 0x800000; - return (jaguarMainRom[offset+0] << 8) | jaguarMainRom[offset+1]; + return (jaguarMainROM[offset+0] << 8) | jaguarMainROM[offset+1]; } // else if ((offset >= 0xDFFF00) && (offset < 0xDFFF00)) else if ((offset >= 0xDFFF00) && (offset <= 0xDFFFFE)) return CDROMReadWord(offset, who); else if ((offset >= 0xE00000) && (offset <= 0xE3FFFE)) - return (jaguarBootRom[(offset+0) & 0x3FFFF] << 8) | jaguarBootRom[(offset+1) & 0x3FFFF]; + return (jaguarBootROM[(offset+0) & 0x3FFFF] << 8) | jaguarBootROM[(offset+1) & 0x3FFFF]; else if ((offset >= 0xF00000) && (offset <= 0xF0FFFE)) return TOMReadWord(offset, who); else if ((offset >= 0xF10000) && (offset <= 0xF1FFFE)) @@ -1173,7 +1406,7 @@ void JaguarWriteByte(uint32 offset, uint8 data, uint32 who/*=UNKNOWN*/) offset &= 0xFFFFFF; if (offset < 0x400000) { - jaguarMainRam[offset & 0x3FFFFF] = data; + jaguarMainRAM[offset & 0x3FFFFF] = data; return; } else if ((offset >= 0xDFFF00) && (offset <= 0xDFFFFF)) @@ -1301,8 +1534,8 @@ if (who == GPU && (gpu_pc == 0xF03604 || gpu_pc == 0xF03638)) if (offset == 0x11D31A + 0x48000 || offset == 0x11D31A) WriteLog("JWW: %s writing star %04X at %08X...\n", whoName[who], data, offset);//*/ - jaguarMainRam[(offset+0) & 0x3FFFFF] = data >> 8; - jaguarMainRam[(offset+1) & 0x3FFFFF] = data & 0xFF; + jaguarMainRAM[(offset+0) & 0x3FFFFF] = data >> 8; + jaguarMainRAM[(offset+1) & 0x3FFFFF] = data & 0xFF; return; } else if (offset >= 0xDFFF00 && offset <= 0xDFFFFE) @@ -1359,13 +1592,13 @@ void JaguarInit(void) memset(writeMemMin, 0xFF, 0x400000); memset(writeMemMax, 0x00, 0x400000); #endif - memset(jaguarMainRam, 0x00, 0x400000); + memset(jaguarMainRAM, 0x00, 0x400000); // memset(jaguar_mainRom, 0xFF, 0x200000); // & set it to all Fs... // memset(jaguar_mainRom, 0x00, 0x200000); // & set it to all 0s... //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... m68k_set_cpu_type(M68K_CPU_TYPE_68000); @@ -1382,11 +1615,14 @@ void RenderCallback(void); //extern uint32 * backbuffer; void JaguarReset(void) { -//NOTE: This causes a (virtual) crash if this is set in the config but not found... !!! FIX !!! - if (vjs.useJaguarBIOS) - memcpy(jaguarMainRam, jaguarBootRom, 8); + // Only use the system BIOS if it's available...! + if (vjs.useJaguarBIOS && (biosAvailable & (BIOS_NORMAL | BIOS_STUB1 | BIOS_STUB2))) + memcpy(jaguarMainRAM, jaguarBootROM, 8); else - SET32(jaguarMainRam, 4, jaguarRunAddress); + 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(); @@ -1480,16 +1716,52 @@ 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: VBL interrupt is %s\n", ((TOMIRQEnabled(IRQ_VBLANK)) && (JaguarInterruptHandlerIsValid(64))) ? "enabled" : "disabled"); + WriteLog("Jaguar: Interrupt enable = $%02X\n", TOMReadByte(0xF000E1, JAGUAR) & 0x1F); + WriteLog("Jaguar: Video interrupt is %s (line=%u)\n", ((TOMIRQEnabled(IRQ_VBLANK)) + && (JaguarInterruptHandlerIsValid(64))) ? "enabled" : "disabled", TOMReadWord(0xF0004E, JAGUAR)); M68K_show_context(); //#endif +#if 0 // This is drawn already... + WriteLog("Jaguar: 68K AutoVector table:\n", JaguarReadWord(0x3004)); + for(uint32 i=0x64; i<=0x7C; i+=4) + WriteLog(" #%u: %08X\n", (i-0x64)/4, JaguarReadLong(i)); +#endif + CDROMDone(); GPUDone(); DSPDone(); TOMDone(); JERRYDone(); + + // temp, until debugger is in place +//00802016: jsr $836F1A.l +//0080201C: jsr $836B30.l +//00802022: jsr $836B18.l +//00802028: jsr $8135F0.l +//00813C1E: jsr $813F76.l +//00802038: jsr $836D00.l +//00802098: jsr $8373A4.l +//008020A2: jsr $83E24A.l +//008020BA: jsr $83E156.l +//008020C6: jsr $83E19C.l +//008020E6: jsr $8445E8.l +//008020EC: jsr $838C20.l +//0080211A: jsr $838ED6.l +//00802124: jsr $89CA56.l +//0080212A: jsr $802B48.l +#if 0 + WriteLog("-------------------------------------------\n"); + JaguarDasm(0x8445E8, 0x200); + WriteLog("-------------------------------------------\n"); + JaguarDasm(0x838C20, 0x200); + WriteLog("-------------------------------------------\n"); + JaguarDasm(0x838ED6, 0x200); + WriteLog("-------------------------------------------\n"); + JaguarDasm(0x89CA56, 0x200); + WriteLog("-------------------------------------------\n"); + JaguarDasm(0x802B48, 0x200); +#endif } // @@ -1497,21 +1769,21 @@ 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 m68kCockRate = (vjs.hardwareTypeNTSC ? M68K_CLOCK_RATE_NTSC : M68K_CLOCK_RATE_PAL); + uint32 m68kClockRate = (vjs.hardwareTypeNTSC ? M68K_CLOCK_RATE_NTSC : M68K_CLOCK_RATE_PAL); //Not sure the above is correct, since the number of lines and timings given in the JTRM //seem to indicate the refresh rate is *half* the above... // uint16 refreshRate = (vjs.hardwareTypeNTSC ? 30 : 25); @@ -1528,9 +1800,9 @@ if (effect_start) for(uint16 i=0; i= 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... @@ -1662,7 +1934,7 @@ void ScanlineCallback(void) // We don't have to worry about autovectors & whatnot because the Jaguar // tells you through its HW registers who sent the interrupt... tom_set_pending_video_int(); - m68k_set_irq(7); + m68k_set_irq(2); } TOMExecScanline(vc, true); @@ -1732,17 +2004,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... @@ -1751,7 +2023,7 @@ void ScanlineCallback(void) // We don't have to worry about autovectors & whatnot because the Jaguar // tells you through its HW registers who sent the interrupt... TOMSetPendingVideoInt(); - m68k_set_irq(7); + m68k_set_irq(2); } TOMExecScanline(vc, true); @@ -1762,7 +2034,8 @@ void ScanlineCallback(void) // if (vc == vbb) { JoystickExec(); - RenderBackbuffer(); +//We comment this out so that the GUI can manage this instead. Which is how it should be anyway. +// RenderBackbuffer(); TOMResetBackbuffer(backbuffer); frameDone = true; }//*/ @@ -1779,7 +2052,7 @@ void ScanlineCallback(void) // This isn't currently used, but maybe it should be... void RenderCallback(void) { - RenderBackbuffer(); +// RenderBackbuffer(); TOMResetBackbuffer(backbuffer); // SetCallbackTime(RenderCallback, 33303.082); // # Scanlines * scanline time SetCallbackTime(RenderCallback, 16651.541); // # Scanlines * scanline time