5 // GCC/SDL port by Niels Wagenaar (Linux/WIN32) and Caz (BeOS)
6 // Cleanups and endian wrongness amelioration by James L. Hammons
7 // Note: Endian wrongness probably stems from the MAME origins of this emu and
8 // the braindead way in which MAME handles memory. :-)
12 #include "m68kdasmAG.h"
15 //#define LOG_UNMAPPED_MEMORY_ACCESSES
16 //#define SOUND_OUTPUT
18 // Some handy macros to help converting native endian to big endian (jaguar native)
20 #define SET32(r, a, v) r[a] = ((v) & 0xFF000000) >> 24, r[a+1] = ((v) & 0x00FF0000) >> 16, \
21 r[a+2] = ((v) & 0x0000FF00) >> 8, r[a+3] = (v) & 0x000000FF
24 // Function Prototypes
27 unsigned jaguar_unknown_readbyte(unsigned address);
28 unsigned jaguar_unknown_readword(unsigned address);
29 void jaguar_unknown_writebyte(unsigned address, unsigned data);
30 void jaguar_unknown_writeword(unsigned address, unsigned data);
38 uint32 jaguar_active_memory_dumps = 0;
39 uint32 jaguar_use_bios = 0;
40 #define JAGUAR_WIP_RELEASE
41 #define JAGUAR_REAL_SPEED
47 //static char *jaguar_bootRom_path="c:/jaguarEmu/newload.img";
48 static char * jaguar_bootRom_path = "./bios/jagboot.rom";
49 //static char *jaguar_bootRom_path="./bios/JagOS.bin";
50 char * jaguar_eeproms_path = "./eeproms/";
52 uint32 jaguar_mainRom_crc32;
54 static uint32 m68k_cycles_per_scanline;
55 static uint32 gpu_cycles_per_scanline;
56 static uint32 dsp_cycles_per_scanline;
57 static uint32 jaguar_screen_scanlines;
59 static uint8 * jaguar_mainRam = NULL;
60 static uint8 * jaguar_bootRom = NULL;
61 static uint8 * jaguar_mainRom = NULL;
65 // Musashi 68000 read/write/IRQ functions
68 int irq_ack_handler(int level)
70 int vector = M68K_INT_ACK_AUTOVECTOR;
74 m68k_set_irq(0); // Clear the IRQ...
75 vector = 64; // Set user interrupt #0
81 //Do this in makefile??? Yes!
82 //#define LOG_UNMAPPED_MEMORY_ACCESSES 1
84 unsigned int m68k_read_memory_8(unsigned int address)
86 //fprintf(log_get(), "[RM8] Addr: %08X\n", address);
87 unsigned int retVal = 0;
89 if ((address >= 0x000000) && (address <= 0x3FFFFF))
90 retVal = jaguar_mainRam[address];
91 else if ((address >= 0x800000) && (address <= 0xDFFFFF))
92 retVal = jaguar_mainRom[address - 0x800000];
93 else if ((address >= 0xE00000) && (address <= 0xE3FFFF))
94 retVal = jaguar_bootRom[address - 0xE00000];
95 else if ((address >= 0xDFFF00) && (address <= 0xDFFFFF))
96 retVal = cdrom_byte_read(address);
97 else if ((address >= 0xF00000) && (address <= 0xF0FFFF))
98 retVal = tom_byte_read(address);
99 else if ((address >= 0xF10000) && (address <= 0xF1FFFF))
100 retVal = jerry_byte_read(address);
102 retVal = jaguar_unknown_readbyte(address);
107 unsigned int m68k_read_memory_16(unsigned int address)
109 //fprintf(log_get(), "[RM16] Addr: %08X\n", address);
110 unsigned int retVal = 0;
112 if ((address >= 0x000000) && (address <= 0x3FFFFE))
113 retVal = (jaguar_mainRam[address] << 8) | jaguar_mainRam[address+1];
114 else if ((address >= 0x800000) && (address <= 0xDFFFFE))
115 retVal = (jaguar_mainRom[address - 0x800000] << 8) | jaguar_mainRom[address - 0x800000 + 1];
116 else if ((address >= 0xE00000) && (address <= 0xE3FFFE))
117 retVal = (jaguar_bootRom[address - 0xE00000] << 8) | jaguar_bootRom[address - 0xE00000 + 1];
118 else if ((address >= 0xDFFF00) && (address <= 0xDFFFFE))
119 retVal = cdrom_word_read(address);
120 else if ((address >= 0xF00000) && (address <= 0xF0FFFE))
121 retVal = tom_word_read(address);
122 else if ((address >= 0xF10000) && (address <= 0xF1FFFE))
123 retVal = jerry_word_read(address);
126 //fprintf(log_get(), "[RM16] Unknown address: %08X\n", address);
127 retVal = jaguar_unknown_readword(address);
133 unsigned int m68k_read_memory_32(unsigned int address)
135 //fprintf(log_get(), "--> [RM32]\n");
136 return (m68k_read_memory_16(address) << 16) | m68k_read_memory_16(address + 2);
139 void m68k_write_memory_8(unsigned int address, unsigned int value)
141 //fprintf(log_get(), "[WM8 PC=%08X] Addr: %08X, val: %02X\n", m68k_get_reg(NULL, M68K_REG_PC), address, value);
142 if ((address >= 0x000000) && (address <= 0x3FFFFF))
143 jaguar_mainRam[address] = value;
144 else if ((address >= 0xDFFF00) && (address <= 0xDFFFFF))
145 cdrom_byte_write(address, value);
146 else if ((address >= 0xF00000) && (address <= 0xF0FFFF))
147 tom_byte_write(address, value);
148 else if ((address >= 0xF10000) && (address <= 0xF1FFFF))
149 jerry_byte_write(address, value);
151 jaguar_unknown_writebyte(address, value);
154 void m68k_write_memory_16(unsigned int address, unsigned int value)
156 //fprintf(log_get(), "[WM16 PC=%08X] Addr: %08X, val: %04X\n", m68k_get_reg(NULL, M68K_REG_PC), address, value);
157 if ((address >= 0x000000) && (address <= 0x3FFFFE))
159 jaguar_mainRam[address] = value >> 8;
160 jaguar_mainRam[address + 1] = value & 0xFF;
162 else if ((address >= 0xDFFF00) && (address <= 0xDFFFFE))
163 cdrom_word_write(address, value);
164 else if ((address >= 0xF00000) && (address <= 0xF0FFFE))
165 tom_word_write(address, value);
166 else if ((address >= 0xF10000) && (address <= 0xF1FFFE))
167 jerry_word_write(address, value);
169 jaguar_unknown_writeword(address, value);
172 void m68k_write_memory_32(unsigned int address, unsigned int value)
174 //fprintf(log_get(), "--> [WM32]\n");
175 m68k_write_memory_16(address, value >> 16);
176 m68k_write_memory_16(address + 2, value & 0xFFFF);
180 //////////////////////////////////////////////////////////////////////////////
182 //////////////////////////////////////////////////////////////////////////////
186 //////////////////////////////////////////////////////////////////////////////
187 uint32 jaguar_get_handler(uint32 i)
189 // return (jaguar_word_read(i<<2) << 16) | jaguar_word_read((i<<2) + 2);
190 // return (jaguar_word_read(i*4) << 16) | jaguar_word_read((i*4) + 2);
191 return jaguar_long_read(i * 4);
194 //////////////////////////////////////////////////////////////////////////////
196 //////////////////////////////////////////////////////////////////////////////
202 //////////////////////////////////////////////////////////////////////////////
203 static char romLoadDialog_filePath[1024];
205 static char romLoadDialog_initialDirectory[1024];
207 int jaguar_open_rom(HWND hWnd, char * title, char * filterString)
210 romLoadDialog_initialDirectory[0] = 0;
211 romLoadDialog_filePath[0] = 0;
213 ZeroMemory(&ofn, sizeof(OPENFILENAME));
214 ofn.lStructSize = sizeof(OPENFILENAME);
215 ofn.hwndOwner = hWnd;
216 ofn.lpstrFile = romLoadDialog_filePath;
217 ofn.nMaxFile = sizeof(romLoadDialog_filePath);
218 ofn.lpstrFilter = filterString;
219 ofn.nFilterIndex = 0;
220 ofn.lpstrFileTitle = NULL;
221 ofn.nMaxFileTitle = 0;
222 ofn.lpstrInitialDir = (const char *)romLoadDialog_initialDirectory;
223 ofn.lpstrTitle = title;
224 ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
226 if(GetOpenFileName(&ofn) == FALSE)
228 DWORD res = CommDlgExtendedError();
229 SendMessage(hWnd, WM_MOVE, 0,0);
234 SendMessage(hWnd, WM_MOVE, 0,0);
238 //////////////////////////////////////////////////////////////////////////////
240 //////////////////////////////////////////////////////////////////////////////
244 //////////////////////////////////////////////////////////////////////////////
245 uint32 jaguar_interrupt_handler_is_valid(uint32 i)
247 uint32 handler = jaguar_get_handler(i);
248 if (handler && (handler != 0xFFFFFFFF))
253 //////////////////////////////////////////////////////////////////////////////
255 //////////////////////////////////////////////////////////////////////////////
259 //////////////////////////////////////////////////////////////////////////////
260 void s68000show_context(void)
262 // fprintf(log_get(),"\t68k PC=0x%.6x\n",s68000readPC());
263 fprintf(log_get(),"\t68k PC=0x%.6x\n", m68k_get_reg(NULL, M68K_REG_PC));
264 // for (int i=0;i<8;i++)
265 // fprintf(log_get(),"\tD%i = 0x%.8x\n",i,s68000context.dreg[i]);
266 for(int i=M68K_REG_D0; i<=M68K_REG_D7; i++)
267 fprintf(log_get(), "\tD%i = 0x%.8x\n", i-M68K_REG_D0, m68k_get_reg(NULL, (m68k_register_t)i));
268 fprintf(log_get(), "\n");
270 // fprintf(log_get(),"\tA%i = 0x%.8x\n",i,s68000context.areg[i]);
271 for(int i=M68K_REG_A0; i<=M68K_REG_A7; i++)
272 fprintf(log_get(), "\tA%i = 0x%.8x\n", i-M68K_REG_A0, m68k_get_reg(NULL, (m68k_register_t)i));
274 fprintf(log_get(), "68k dasm\n");
275 // jaguar_dasm(s68000readPC()-0x1000,0x20000);
276 // jaguar_dasm(m68k_get_reg(NULL, M68K_REG_PC) - 0x1000, 0x20000);
277 jaguar_dasm(m68k_get_reg(NULL, M68K_REG_PC) - 0x80, 0x200);
278 fprintf(log_get(), "..................\n");
281 if (tom_irq_enabled(IRQ_VBLANK))
283 fprintf(log_get(), "vblank int: enabled\n");
284 jaguar_dasm(jaguar_get_handler(64), 0x200);
287 fprintf(log_get(), "vblank int: disabled\n");
288 fprintf(log_get(), "..................\n");
290 for(int i=0; i<256; i++)
291 fprintf(log_get(), "handler %03i at $%08X\n", i, jaguar_get_handler(i));
294 // Starscream crap ripped out...
297 // Unknown read/write byte/word routines
300 void jaguar_unknown_writebyte(unsigned address, unsigned data)
302 #ifdef LOG_UNMAPPED_MEMORY_ACCESSES
303 fprintf(log_get(), "jaguar: unknown byte %02X write at %08X (PC=%06X)\n", data, address, m68k_get_reg(NULL, M68K_REG_PC));
307 void jaguar_unknown_writeword(unsigned address, unsigned data)
309 #ifdef LOG_UNMAPPED_MEMORY_ACCESSES
310 fprintf(log_get(), "jaguar: unknown word %04X write at %08X (PC=%06X)\n", data, address, m68k_get_reg(NULL, M68K_REG_PC));
314 unsigned jaguar_unknown_readbyte(unsigned address)
316 #ifdef LOG_UNMAPPED_MEMORY_ACCESSES
317 fprintf(log_get(), "jaguar: unknown byte read at %08X (PC=%06X)\n", address, m68k_get_reg(NULL, M68K_REG_PC));
322 unsigned jaguar_unknown_readword(unsigned address)
324 #ifdef LOG_UNMAPPED_MEMORY_ACCESSES
325 fprintf(log_get(), "jaguar: unknown word read at %08X (PC=%06X)\n", address, m68k_get_reg(NULL, M68K_REG_PC));
331 // Jaguar ROM loading
334 uint8 * jaguar_rom_load(char * path, uint32 * romSize)
338 fprintf(log_get(), "jaguar: loading %s...", path);
339 FILE * fp = fopen(path, "rb");
342 fprintf(log_get(), "failed\n");
347 fseek(fp, 0, SEEK_END);
349 /* Added by SDLEMU (http://sdlemu.ngemu.com) */
350 /* Added for GCC UNIX compatibility */
352 fgetpos(fp, (fpos_t *)&filepos);
354 fgetpos(fp, &filepos);
357 *romSize = (int)filepos;
358 fseek(fp, 0, SEEK_SET);
359 uint8 * rom = (uint8 *)malloc(*romSize);
360 fread(rom, 1, *romSize, fp);
362 fprintf(log_get(), "ok (%i bytes)\n", *romSize);
363 // jaguar_mainRom_crc32=crc32_calcCheckSum(jaguar_mainRom,*romSize);
364 // fprintf(log_get(),"crc: 0x%.8x\n",jaguar_mainRom_crc32);
369 // Load a ROM at a specific address
372 void jaguar_rom_load_to(uint8 * rom, char * path, uint32 * romSize)
376 fprintf(log_get(), "jaguar: loading %s...", path);
377 FILE * fp = fopen(path, "rb");
380 fprintf(log_get(), "failed\n");
385 fseek(fp, 0, SEEK_END);
387 /* Added by SDLEMU (http://sdlemu.ngemu.com) */
388 /* Added for GCC UNIX compatibility */
390 fgetpos(fp, (fpos_t *)&filepos);
392 fgetpos(fp, &filepos);
395 *romSize = (int)filepos;
396 fseek(fp, 0, SEEK_SET);
397 fread(rom, 1, *romSize, fp);
399 fprintf(log_get(), "ok (%i bytes)\n", *romSize);
403 // Byte swap a region of memory
406 /*void jaguar_byte_swap(uint8 * rom, uint32 size)
419 // Disassemble instructions at the given offset
422 void jaguar_dasm(uint32 offset, uint32 qt)
425 static char buffer[2048], mem[64];
426 int pc = offset, oldpc;
428 for(int i=0; i<qt; i++)
431 for(int j=0; j<64; j++)
432 mem[j^0x01] = jaguar_byte_read(pc + j);
434 pc += Dasm68000((char *)mem, buffer, 0);
435 fprintf(log_get(), "%08X: %s\n", oldpc, buffer);
441 // Jaguar cartridge ROM loading
444 void jaguar_load_cart(char * path, uint8 * mem, uint32 offs, uint32 boot, uint32 header)
448 jaguar_rom_load_to(mem+offs-header, path, &romsize);
449 // Is there a need for this? The answer is !!! NO !!!
450 // jaguar_byte_swap(mem+offs, romsize);
451 jaguar_mainRom_crc32 = crc32_calcCheckSum(jaguar_mainRom, romsize);
452 fprintf(log_get(), "CRC: %08X\n", jaguar_mainRom_crc32);
454 // Brain dead endian dependent crap
455 // *((uint32 *)&jaguar_mainRam[4]) = boot;
456 // This is how it *should* have been done...
457 SET32(jaguar_mainRam, 4, boot);
459 // jaguar_dasm((boot>>16) | (boot<<16), 32*4);
460 jaguar_dasm(boot, 32*4);
464 // Jaguar initialization
468 void jaguar_init(const char * filename)
470 void jaguar_init(void)
475 jaguar_screen_scanlines = 525; // PAL screen size
476 m68k_cycles_per_scanline = 13300000 / (jaguar_screen_scanlines * 60);
477 gpu_cycles_per_scanline = (26591000 / 4) / (jaguar_screen_scanlines * 60);
478 dsp_cycles_per_scanline = (26591000 / 4) / (jaguar_screen_scanlines * 60);
480 memory_malloc_secure((void **)&jaguar_mainRam, 0x400000, "Jaguar 68k cpu ram");
481 memory_malloc_secure((void **)&jaguar_bootRom, 0x040000, "Jaguar 68k cpu boot rom");
482 memory_malloc_secure((void **)&jaguar_mainRom, 0x600000, "Jaguar 68k cpu rom");
483 memset(jaguar_mainRam, 0x00, 0x400000);
485 jaguar_rom_load_to(jaguar_bootRom, jaguar_bootRom_path, &romsize);
486 // No need to do this anymore, since Starcrap is gone!
487 // jaguar_byte_swap(jaguar_bootRom, romsize);
488 memcpy(jaguar_mainRam, jaguar_bootRom, 8);
489 // More braindead endian dependent crap
490 //WAS: *((uint32 *)&jaguar_mainRam[0]) = 0x00000020;
491 SET32(jaguar_mainRam, 0, 0x00200000);
493 #ifdef JAGUAR_WIP_RELEASE
495 strcpy(romLoadDialog_filePath, filename);
497 jaguar_open_rom(GetForegroundWindow(), "Load", "Jaguar roms (*.JAG)\0*.JAG\0\0");
499 //WAS: jaguar_load_cart(romLoadDialog_filePath, jaguar_mainRom, 0x0000, 0x20000080, 0);
500 jaguar_load_cart(romLoadDialog_filePath, jaguar_mainRom, 0x0000, 0x00802000, 0);
503 /* if (jaguar_mainRom_crc32 == 0xA9F8A00E)
506 fprintf(log_get(), "--> Rayman detected, DSP enabled...\n");
510 if ((jaguar_mainRom_crc32 == 0x3966698f) || (jaguar_mainRom_crc32 == 0x5e705756)
511 || (jaguar_mainRom_crc32 == 0x2630cbc4) || (jaguar_mainRom_crc32 == 0xd46437e8)
512 || (jaguar_mainRom_crc32 == 0x2630cbc4))
515 if ((jaguar_mainRom_crc32 == 0x6e90989f) || (jaguar_mainRom_crc32 == 0xfc8f0dcd)
516 || (jaguar_mainRom_crc32 == 0x2a512a83) || (jaguar_mainRom_crc32 == 0x41307601)
517 || (jaguar_mainRom_crc32 == 0x3c7bfda8) || (jaguar_mainRom_crc32 == 0x5e705756))
518 gpu_cycles_per_scanline = (26591000 / 1) / (jaguar_screen_scanlines * 60);
520 if (jaguar_mainRom_crc32 == 0x7ae20823)
523 gpu_cycles_per_scanline = (26591000 / 1) / (jaguar_screen_scanlines * 60);
524 dsp_cycles_per_scanline = (26591000 / 1) / (jaguar_screen_scanlines * 60);
526 if (jaguar_mainRom_crc32 == 0xe21d0e2f)
529 gpu_cycles_per_scanline = (26591000 / 1) / (jaguar_screen_scanlines * 60);
530 dsp_cycles_per_scanline = (26591000 / 1) / (jaguar_screen_scanlines * 60);
532 if (jaguar_mainRom_crc32 == 0x66f8914c)
534 gpu_cycles_per_scanline = (26591000 / 1) /(jaguar_screen_scanlines * 60);
536 if (jaguar_mainRom_crc32 == 0x5a5b9c68)
538 gpu_cycles_per_scanline = (26591000 / 1) / (jaguar_screen_scanlines * 60);
540 if (jaguar_mainRom_crc32 == 0xdcb0197a)
542 dsp_enabled = 0; // dsp not needed
543 gpu_cycles_per_scanline = (26591000 / 1) / (jaguar_screen_scanlines * 60);
544 //dsp_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60);
546 if ((jaguar_mainRom_crc32 == 0x3966698f) || (jaguar_mainRom_crc32 == 0xe21d0e2f))
548 if (jaguar_mainRom_crc32 == 0x5e705756)
550 gpu_cycles_per_scanline = (26591000 / 1) / (jaguar_screen_scanlines * 60);
553 if (jaguar_mainRom_crc32 == 0x2630cbc4)
556 gpu_cycles_per_scanline = (26591000 / 1) / (jaguar_screen_scanlines * 60);
557 dsp_cycles_per_scanline = (26591000 / 1) / (jaguar_screen_scanlines * 60);
560 if ((jaguar_mainRom_crc32 == 0xd46437e8) || (jaguar_mainRom_crc32 == 0xba74c3ed))
562 gpu_cycles_per_scanline = (26591000 / 1) / (jaguar_screen_scanlines * 60);
565 if (jaguar_mainRom_crc32 == 0x6e90989f)
566 gpu_cycles_per_scanline = (26591000 / 1) / (jaguar_screen_scanlines * 60);
568 if (jaguar_mainRom_crc32 == 0x41307601)
570 gpu_cycles_per_scanline = (26591000 / 1) / (jaguar_screen_scanlines * 60);
573 if (jaguar_mainRom_crc32 == 0x8483392b)
578 #else // #ifdef JAGUAR_WIP_RELEASE
579 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/flashback.jag",jaguar_mainRom,0x0000, 0x20000080,0);
580 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/Pinball Fantasies.JAG",jaguar_mainRom,0x0000, 0x20000080,0);
581 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/alien vs predator (1994).jag",jaguar_mainRom,0x0000, 0x20000080,0);
582 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/cannon fodder (1995) (computer west).jag",jaguar_mainRom,0x0000, 0x20000080,0);
583 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/double dragon v (1995) (williams).jag",jaguar_mainRom,0x0000, 0x20000080,0);
584 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/Dragon - The Bruce Lee Story.JAG",jaguar_mainRom,0x0000, 0x20000080,0);
585 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/Syndicate.JAG",jaguar_mainRom,0x0000, 0x20000080,0);
586 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/Theme Park.JAG",jaguar_mainRom,0x0000, 0x20000080,0);
587 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/Brutal Sports Football.JAG",jaguar_mainRom,0x0000, 0x20000080,0);
588 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/International Sensible Soccer.JAG",jaguar_mainRom,0x0000, 0x20000080,0);
589 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/Defender 2000.JAG",jaguar_mainRom,0x0000, 0x20000080,0);
590 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/Fever Pitch Soccer.JAG",jaguar_mainRom,0x0000, 0x20000080,0);
591 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/Rayman.JAG",jaguar_mainRom,0x0000, 0x20000080,0);
592 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/Tempest 2000.JAG",jaguar_mainRom,0x0000, 0x20000080,0);
593 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/zool 2 (1994).jag",jaguar_mainRom,0x0000, 0x20000080,0);
594 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/Bubsy - Fractured Furry Tails.JAG",jaguar_mainRom,0x0000, 0x20000080,0);
595 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/Raiden.JAG",jaguar_mainRom,0x0000, 0x20000080,0);
596 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/Dino Olympics.jag",jaguar_mainRom,0x0000, 0x20000080,0);
597 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/I-War.jag",jaguar_mainRom,0x0000, 0x20000080,0);
598 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/Attack of the Mutant Penguins.JAG",jaguar_mainRom,0x0000, 0x20000080,0);
599 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/Cybermorph.jag",jaguar_mainRom,0x0000, 0x20000080,0);
600 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/Troy Aikman NFL Football (1995) (Williams).jag",jaguar_mainRom,0x0000, 0x20000080,0);
601 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/Power Drive Rally (1995) (TWI).jag",jaguar_mainRom,0x0000, 0x20000080,0);
602 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/Zoop! (1996).jag",jaguar_mainRom,0x0000, 0x20000080,0);
603 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/Missile Command 3D.JAG",jaguar_mainRom,0x0000, 0x20000080,0);
604 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/Hover Strike.jag",jaguar_mainRom,0x0000, 0x20000080,0);
605 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/worms.bin",jaguar_mainRom,0x0000, 0x20000080,0);
606 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/Atari Kart.JAG",jaguar_mainRom,0x0000, 0x20000080,0);
607 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/native.bin",jaguar_mainRam,0x5000, 0x50000000,0x00);
609 if (jaguar_mainRom_crc32==0xe21d0e2f)
612 gpu_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60);
613 dsp_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60);
615 if (jaguar_mainRom_crc32==0x66f8914c)
617 gpu_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60);
619 if (jaguar_mainRom_crc32==0x5a5b9c68)
621 gpu_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60);
623 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/Super Cross 3D.JAG",jaguar_mainRom,0x0000, 0x20000080,0);
624 if (jaguar_mainRom_crc32==0xdcb0197a)
626 dsp_enabled=0; // dsp not needed
627 gpu_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60);
628 //dsp_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60);
630 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/wolfenstein 3d (1994).jag",jaguar_mainRom,0x0000, 0x20000080,0);
631 if ((jaguar_mainRom_crc32==0x3966698f)||(jaguar_mainRom_crc32==0xe21d0e2f))
633 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/NBA JAM.jag",jaguar_mainRom,0x0000, 0x20000080,0);
634 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/Doom - Evil Unleashed.JAG",jaguar_mainRom,0x0000, 0x20000080,0);
635 if (jaguar_mainRom_crc32==0x5e705756)
637 gpu_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60);
640 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/Ultra Vortek.JAG",jaguar_mainRom,0x0000, 0x20000080,0);
641 if (jaguar_mainRom_crc32==0x2630cbc4)
644 gpu_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60);
645 dsp_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60);
648 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/fflbeta.rom",jaguar_mainRom,0x0000, 0x20000080,0);
649 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/Fight for Your Life.jag",jaguar_mainRom,0x0000, 0x20000080,0);
650 if ((jaguar_mainRom_crc32==0xd46437e8)||(jaguar_mainRom_crc32==0xba74c3ed))
652 gpu_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60);
653 // dsp_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60);
656 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/Pitfall - The Mayan Adventure.JAG",jaguar_mainRom,0x0000, 0x20000080,0);
657 if (jaguar_mainRom_crc32==0x6e90989f)
658 gpu_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60);
660 // missing some sprites
661 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/Crescent Galaxy.jag",jaguar_mainRom,0x0000, 0x20000080,0);
662 if (jaguar_mainRom_crc32==0x41307601)
664 gpu_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60);
667 // missing vertical bar shades
668 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/Phase Zero (2000) (PD).rom",jaguar_mainRom,0x0000, 0x20000080,0);
669 if (jaguar_mainRom_crc32==0x8483392b)
673 // cpu/dsp/gpu synchronization problems
676 // locks up during the game
677 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/Club Drive.JAG",jaguar_mainRom,0x0000, 0x20000080,0);
679 // no parallax floor, locks up at the start of the game
680 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/Kasumi Ninja.JAG",jaguar_mainRom,0x0000, 0x20000080,0);
682 // displaying the sound control dialog. no way to exit from it
683 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/Checkered Flag.JAG",jaguar_mainRom,0x0000, 0x20000080,0);
686 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/Iron Soldier.jag",jaguar_mainRom,0x0000, 0x20000080,0);
688 // locks up at the start of the game
689 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/Super Burnout.JAG",jaguar_mainRom,0x0000, 0x20000080,0);
690 if (jaguar_mainRom_crc32==0x20ae75f4)
693 gpu_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60);
694 dsp_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60);
696 // locks up at the start of the game
697 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/Val D'Isere Skiing & Snowboarding (1994).jag",jaguar_mainRom,0x0000, 0x20000080,0);
698 if (jaguar_mainRom_crc32==0x4664ebd1)
703 // fonctionne avec le gpu et le dsp activés et gpu à frequence nominale, et dsp à 1/4 de la frequence nominale
704 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/white men can't jump (1995).jag",jaguar_mainRom,0x0000, 0x20000080,0);
705 if (jaguar_mainRom_crc32==0x7ae20823)
708 gpu_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60);
710 // not working at all
711 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/Flip Out.JAG",jaguar_mainRom,0x0000, 0x20000080,0);
712 if (jaguar_mainRom_crc32==0x6f57dcd2)
714 gpu_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60);
719 jaguar_load_cart("C:/ftp/jaguar/roms/roms/Ruiner.JAG",jaguar_mainRom,0x0000, 0x20000080,0);
720 if (jaguar_mainRom_crc32==0x6a7c7430)
725 if (jaguar_mainRom_crc32==0x2f032271)
728 dsp_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60);
729 gpu_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60);
731 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/tetris.bin",jaguar_mainRam,0x4fe4, 0x50000000,0x00);
732 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/painter.bin",jaguar_mainRam,0xffe4, 0x00000001,0x00);
733 // jaguar_load_cart("./roms/jagcd.rom",jaguar_mainRom,0x0000, 0x20000080,0);
735 // jaguar_load_cart("cart.jag",jaguar_mainRom,0x0000, 0x20000080,0);
738 // cd_bios_boot("C:\\ftp\\jaguar\\cd\\Brain Dead 13.cdi");
739 // cd_bios_boot("C:\\ftp\\jaguar\\cd\\baldies.cdi");
740 // cd_bios_boot("C:\\ftp\\jaguar\\cd\\mystdemo.cdi");
741 // cd_bios_boot("C:\\ftp\\jaguar\\cd\\battlemorph.cdi");
742 // cd_bios_boot("C:\\ftp\\jaguar\\cd\\primalrage.cdi");
743 // cd_bios_boot("C:\\ftp\\jaguar\\cd\\Dragons Lair.cdi");
745 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/raw.jag",jaguar_mainRam,0x4000, 0x40000000,0x00);
746 #endif // #ifdef JAGUAR_WIP_RELEASE
748 #ifdef JAGUAR_REAL_SPEED
749 gpu_cycles_per_scanline = (26591000 / 1) / (jaguar_screen_scanlines * 60);
750 dsp_cycles_per_scanline = (26591000 / 1) / (jaguar_screen_scanlines * 60);
757 memcpy(jaguar_mainRam, jaguar_bootRom, 8);
758 // *((uint32 *)&jaguar_mainRam[0]) = 0x00000020;
759 // SET32(jaguar_mainRam, 0, 0x00200000);
763 m68k_set_cpu_type(M68K_CPU_TYPE_68000);
771 unsigned jaguar_byte_read(unsigned int offset)
776 if (offset < 0x400000)
777 // data = (jaguar_mainRam[(offset^0x01) & 0x3FFFFF]);
778 data = jaguar_mainRam[offset & 0x3FFFFF];
779 else if ((offset >= 0x800000) && (offset < 0xC00000))
780 // data = (jaguar_mainRom[(offset^0x01)-0x800000]);
781 data = jaguar_mainRom[offset - 0x800000];
782 // else if ((offset >= 0xDFFF00) && (offset < 0xDFFF00))
783 else if ((offset >= 0xDFFF00) && (offset <= 0xDFFFFF))
784 data = cdrom_byte_read(offset);
785 else if ((offset >= 0xE00000) && (offset < 0xE40000))
786 // data = (jaguar_bootRom[(offset^0x01) & 0x3FFFF]);
787 data = jaguar_bootRom[offset & 0x3FFFF];
788 else if ((offset >= 0xF00000) && (offset < 0xF10000))
789 data = tom_byte_read(offset);
790 else if ((offset >= 0xF10000) && (offset < 0xF20000))
791 data = jerry_byte_read(offset);
793 data = jaguar_unknown_readbyte(offset);
798 unsigned jaguar_word_read(unsigned int offset)
801 if (offset <= 0x3FFFFE)
803 // return (jaguar_mainRam[(offset+1) & 0x3FFFFF] << 8) | jaguar_mainRam[(offset+0) & 0x3FFFFF];
804 return (jaguar_mainRam[(offset+0) & 0x3FFFFF] << 8) | jaguar_mainRam[(offset+1) & 0x3FFFFF];
806 else if ((offset >= 0x800000) && (offset <= 0xBFFFFE))
809 // return (jaguar_mainRom[offset+1] << 8) | jaguar_mainRom[offset+0];
810 return (jaguar_mainRom[offset+0] << 8) | jaguar_mainRom[offset+1];
812 // else if ((offset >= 0xDFFF00) && (offset < 0xDFFF00))
813 else if ((offset >= 0xDFFF00) && (offset <= 0xDFFFFE))
814 return cdrom_word_read(offset);
815 else if ((offset >= 0xE00000) && (offset <= 0xE3FFFE))
816 // return *((uint16 *)&jaguar_bootRom[offset & 0x3FFFF]);
817 return (jaguar_bootRom[(offset+0) & 0x3FFFF] << 8) | jaguar_bootRom[(offset+1) & 0x3FFFF];
818 else if ((offset >= 0xF00000) && (offset <= 0xF0FFFE))
819 return tom_word_read(offset);
820 else if ((offset >= 0xF10000) && (offset <= 0xF1FFFE))
821 return jerry_word_read(offset);
823 return jaguar_unknown_readword(offset);
826 void jaguar_byte_write(unsigned offset, unsigned data)
829 if (offset < 0x400000)
831 // jaguar_mainRam[(offset^0x01) & 0x3FFFFF] = data;
832 jaguar_mainRam[offset & 0x3FFFFF] = data;
835 // else if ((offset >= 0xDFFF00) && (offset < 0xDFFF00))
836 else if ((offset >= 0xDFFF00) && (offset <= 0xDFFFFF))
838 cdrom_byte_write(offset, data);
841 else if ((offset >= 0xF00000) && (offset <= 0xF0FFFF))
843 tom_byte_write(offset, data);
846 else if ((offset >= 0xF10000) && (offset <= 0xF1FFFF))
848 jerry_byte_write(offset, data);
852 jaguar_unknown_writebyte(offset, data);
855 void jaguar_word_write(unsigned offset, unsigned data)
859 if (offset <= 0x3FFFFE)
861 // jaguar_mainRam[(offset+0) & 0x3FFFFF] = data & 0xFF;
862 // jaguar_mainRam[(offset+1) & 0x3FFFFF] = (data>>8) & 0xFF;
863 jaguar_mainRam[(offset+0) & 0x3FFFFF] = (data>>8) & 0xFF;
864 jaguar_mainRam[(offset+1) & 0x3FFFFF] = data & 0xFF;
867 else if ((offset >= 0xDFFF00) && (offset <= 0xDFFFFE))
869 cdrom_word_write(offset, data);
872 else if ((offset >= 0xF00000) && (offset <= 0xF0FFFE))
874 tom_word_write(offset, data);
877 else if ((offset >= 0xF10000) && (offset <= 0xF1FFFE))
879 jerry_word_write(offset, data);
883 jaguar_unknown_writeword(offset, data);
886 unsigned jaguar_long_read(unsigned int offset)
888 /* uint32 data = jaguar_word_read(offset);
889 data = (data<<16) | jaguar_word_read(offset+2);
891 return (jaguar_word_read(offset) << 16) | jaguar_word_read(offset+2);
894 void jaguar_long_write(unsigned offset, unsigned data)
896 jaguar_word_write(offset, data >> 16);
897 jaguar_word_write(offset+2, data & 0xFFFF);
900 void jaguar_done(void)
902 fprintf(log_get(), "jaguar_done() ...START\n");
904 fprintf(log_get(), "jaguar: top of stack: %08X\n", jaguar_long_read(0x001FFFF8));
905 // fprintf(log_get(),"jaguar: cd bios version 0x%.4x\n",jaguar_word_read(0x3004));
906 // fprintf(log_get(),"jaguar: vbl interrupt is %s\n",((tom_irq_enabled(IRQ_VBLANK))&&(jaguar_interrupt_handler_is_valid(64)))?"enabled":"disabled");
907 s68000show_context();
916 // jaguar_regionsDone();
917 memory_free(jaguar_mainRom);
918 memory_free(jaguar_bootRom);
919 memory_free(jaguar_mainRam);
920 fprintf(log_get(), "jaguar_done() ...END\n");
923 void jaguar_reset(void)
925 // fprintf(log_get(),"jaguar_reset():\n");
936 m68k_pulse_reset(); // Reset the 68000
937 fprintf(log_get(), "\t68K PC=%06X SP=%08X\n", m68k_get_reg(NULL, M68K_REG_PC), m68k_get_reg(NULL, M68K_REG_A7));
940 void jaguar_reset_handler(void)
944 void jaguar_exec(int16 * backbuffer, uint8 render)
946 uint32 i, vblank_duration = tom_get_vdb();
949 if ((tom_irq_enabled(IRQ_VBLANK)) && (jaguar_interrupt_handler_is_valid(64)))
951 if (jaguar_word_read(0xF0004E) != 0xFFFF)
953 tom_set_pending_video_int();
954 // s68000interrupt(7, IRQ_VBLANK+64);
955 // s68000flushInterrupts();
956 m68k_set_irq(7); // IRQ_VBLANK+64??? Not autovectored??? No.
957 // Could set a global variable here, to signal that this is a VBLANK interrupt...
958 // Then again, since IRQ_VBLANK is set to zero, this would not be necessary in this case.
962 for(i=0; i<vblank_duration; i++)
964 /* uint32 invalid_instruction_address = s68000exec(m68k_cycles_per_scanline);
965 if (invalid_instruction_address != 0x80000000)
966 cd_bios_process(invalid_instruction_address);*/
967 m68k_execute(m68k_cycles_per_scanline);
968 // No CD handling... Hmm...
971 tom_pit_exec(m68k_cycles_per_scanline);
972 tom_exec_scanline(backbuffer, i, 0);
973 jerry_pit_exec(m68k_cycles_per_scanline);
974 jerry_i2s_exec(m68k_cycles_per_scanline);
975 gpu_exec(gpu_cycles_per_scanline);
977 dsp_exec(dsp_cycles_per_scanline);
980 for (; i<jaguar_screen_scanlines; i++)
982 /* uint32 invalid_instruction_address = s68000exec(m68k_cycles_per_scanline);
983 if (invalid_instruction_address != 0x80000000)
984 cd_bios_process(invalid_instruction_address);*/
985 m68k_execute(m68k_cycles_per_scanline);
986 // No CD handling... Hmm...
988 tom_pit_exec(m68k_cycles_per_scanline);
989 jerry_pit_exec(m68k_cycles_per_scanline);
990 jerry_i2s_exec(m68k_cycles_per_scanline);
991 tom_exec_scanline(backbuffer, i, render);
992 gpu_exec(gpu_cycles_per_scanline);
994 dsp_exec(dsp_cycles_per_scanline);
995 backbuffer += tom_width;
998 system_sound_update();
1002 // Temp debugging stuff
1004 void DumpMainMemory(void)
1006 FILE * fp = fopen("./memdump.bin", "wb");
1011 fwrite(jaguar_mainRam, 1, 0x400000, fp);
1012 // for(int i=0; i<0x400000; i++)
1013 // fprintf(fp, "%c", jaguar_mainRam[i]);
1014 // fputc(jaguar_mainRam[i], fp);
1019 uint8 * GetRamPtr(void)
1021 return jaguar_mainRam;