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 #define JAGUAR_WIP_RELEASE
19 #define JAGUAR_REAL_SPEED
20 //Do this in makefile??? Yes! Could, but it's easier to define here...
21 //#define LOG_UNMAPPED_MEMORY_ACCESSES
24 // Private 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);
31 void M68K_show_context(void);
33 // These values are overridden by command line switches...
35 bool dsp_enabled = false;
36 bool jaguar_use_bios = true; // Default is now to USE the BIOS
37 uint32 jaguar_active_memory_dumps = 0;
39 uint32 jaguar_mainRom_crc32;
41 static uint32 m68k_cycles_per_scanline;
42 static uint32 gpu_cycles_per_scanline;
43 static uint32 dsp_cycles_per_scanline;
44 static uint32 jaguar_screen_scanlines;
46 /*static*/ uint8 * jaguar_mainRam = NULL;
47 /*static*/ uint8 * jaguar_bootRom = NULL;
48 /*static*/ uint8 * jaguar_mainRom = NULL;
52 // Callback function to detect illegal instructions
55 void M68KInstructionHook(void)
57 uint32 m68kPC = m68k_get_reg(NULL, M68K_REG_PC);
59 if (!m68k_is_valid_instruction(jaguar_word_read(m68kPC), M68K_CPU_TYPE_68000))
61 WriteLog("\nEncountered illegal instruction at %08X!!!\n\nAborting!\n", m68kPC);
62 uint32 topOfStack = m68k_get_reg(NULL, M68K_REG_A7);
63 WriteLog("M68K: Top of stack: %08X. Stack trace:\n", jaguar_long_read(topOfStack));
64 for(int i=0; i<10; i++)
65 WriteLog("%06X: %08X\n", topOfStack - (i * 4), jaguar_long_read(topOfStack - (i * 4)));
66 WriteLog("Jaguar: VBL interrupt is %s\n", ((tom_irq_enabled(IRQ_VBLANK)) && (jaguar_interrupt_handler_is_valid(64))) ? "enabled" : "disabled");
74 // Musashi 68000 read/write/IRQ functions
77 int irq_ack_handler(int level)
79 int vector = M68K_INT_ACK_AUTOVECTOR;
81 // The GPU/DSP/etc are probably *not* issuing an NMI, but it seems to work OK...
85 m68k_set_irq(0); // Clear the IRQ...
86 vector = 64; // Set user interrupt #0
92 unsigned int m68k_read_memory_8(unsigned int address)
94 //WriteLog( "[RM8] Addr: %08X\n", address);
95 unsigned int retVal = 0;
97 if ((address >= 0x000000) && (address <= 0x3FFFFF))
98 retVal = jaguar_mainRam[address];
99 else if ((address >= 0x800000) && (address <= 0xDFFFFF))
100 retVal = jaguar_mainRom[address - 0x800000];
101 else if ((address >= 0xE00000) && (address <= 0xE3FFFF))
102 retVal = jaguar_bootRom[address - 0xE00000];
103 else if ((address >= 0xDFFF00) && (address <= 0xDFFFFF))
104 retVal = cdrom_byte_read(address);
105 else if ((address >= 0xF00000) && (address <= 0xF0FFFF))
106 retVal = tom_byte_read(address);
107 else if ((address >= 0xF10000) && (address <= 0xF1FFFF))
108 retVal = jerry_byte_read(address);
110 retVal = jaguar_unknown_readbyte(address);
115 void gpu_dump_disassembly(void);
116 void gpu_dump_registers(void);
118 unsigned int m68k_read_memory_16(unsigned int address)
120 //WriteLog( "[RM16] Addr: %08X\n", address);
121 /*if (m68k_get_reg(NULL, M68K_REG_PC) == 0x00005FBA)
122 // for(int i=0; i<10000; i++)
123 WriteLog("[M68K] In routine #6!\n");//*/
124 //if (m68k_get_reg(NULL, M68K_REG_PC) == 0x00006696) // GPU Program #4
125 //if (m68k_get_reg(NULL, M68K_REG_PC) == 0x00005B3C) // GPU Program #2
126 /*if (m68k_get_reg(NULL, M68K_REG_PC) == 0x00005BA8) // GPU Program #3
128 WriteLog("[M68K] About to run GPU! (Addr:%08X, data:%04X)\n", address, tom_word_read(address));
129 gpu_dump_registers();
130 gpu_dump_disassembly();
131 // for(int i=0; i<10000; i++)
132 // WriteLog( "[M68K] About to run GPU!\n");
134 //WriteLog( "[WM8 PC=%08X] Addr: %08X, val: %02X\n", m68k_get_reg(NULL, M68K_REG_PC), address, value);
135 /*if (m68k_get_reg(NULL, M68K_REG_PC) >= 0x00006696 && m68k_get_reg(NULL, M68K_REG_PC) <= 0x000066A8)
137 if (address == 0x000066A0)
139 gpu_dump_registers();
140 gpu_dump_disassembly();
142 for(int i=0; i<10000; i++)
143 WriteLog( "[M68K] About to run GPU! (Addr:%08X, data:%04X)\n", address, tom_word_read(address));
145 unsigned int retVal = 0;
147 if ((address >= 0x000000) && (address <= 0x3FFFFE))
148 retVal = (jaguar_mainRam[address] << 8) | jaguar_mainRam[address+1];
149 else if ((address >= 0x800000) && (address <= 0xDFFFFE))
150 retVal = (jaguar_mainRom[address - 0x800000] << 8) | jaguar_mainRom[address - 0x800000 + 1];
151 else if ((address >= 0xE00000) && (address <= 0xE3FFFE))
152 retVal = (jaguar_bootRom[address - 0xE00000] << 8) | jaguar_bootRom[address - 0xE00000 + 1];
153 else if ((address >= 0xDFFF00) && (address <= 0xDFFFFE))
154 retVal = cdrom_word_read(address);
155 else if ((address >= 0xF00000) && (address <= 0xF0FFFE))
156 retVal = tom_word_read(address);
157 else if ((address >= 0xF10000) && (address <= 0xF1FFFE))
158 retVal = jerry_word_read(address);
161 //WriteLog( "[RM16] Unknown address: %08X\n", address);
162 retVal = jaguar_unknown_readword(address);
168 unsigned int m68k_read_memory_32(unsigned int address)
170 //WriteLog( "--> [RM32]\n");
171 return (m68k_read_memory_16(address) << 16) | m68k_read_memory_16(address + 2);
174 void m68k_write_memory_8(unsigned int address, unsigned int value)
176 //if ((address >= 0x1FF020 && address <= 0x1FF03F) || (address >= 0x1FF820 && address <= 0x1FF83F))
177 // WriteLog("M68K: Writing %02X at %08X\n", value, address);
178 //WriteLog( "[WM8 PC=%08X] Addr: %08X, val: %02X\n", m68k_get_reg(NULL, M68K_REG_PC), address, value);
179 if ((address >= 0x000000) && (address <= 0x3FFFFF))
180 jaguar_mainRam[address] = value;
181 else if ((address >= 0xDFFF00) && (address <= 0xDFFFFF))
182 cdrom_byte_write(address, value);
183 else if ((address >= 0xF00000) && (address <= 0xF0FFFF))
184 tom_byte_write(address, value);
185 else if ((address >= 0xF10000) && (address <= 0xF1FFFF))
186 jerry_byte_write(address, value);
188 jaguar_unknown_writebyte(address, value);
191 void m68k_write_memory_16(unsigned int address, unsigned int value)
193 extern int dsp_pc;//, dsp_control;
194 if (address == 0xF1A116 && (value & 0x01))
196 WriteLog(" M68K(16): DSP is GO! (DSP_PC: %08X)\n\n", dsp_pc);
198 /* static char buffer[512];
200 while (j <= 0xF1BFFF)
203 j += dasmjag(JAGUAR_DSP, buffer, j);
204 WriteLog( "\t%08X: %s\n", oldj, buffer);
209 // WriteLog("M68K(16): DSP halted... (Old value: %08X)\n", dsp_control);
211 //if ((address >= 0x1FF020 && address <= 0x1FF03F) || (address >= 0x1FF820 && address <= 0x1FF83F))
212 // WriteLog("M68K: Writing %04X at %08X\n", value, address);
213 //WriteLog( "[WM16 PC=%08X] Addr: %08X, val: %04X\n", m68k_get_reg(NULL, M68K_REG_PC), address, value);
214 //if (address >= 0xF02200 && address <= 0xF0229F)
215 // WriteLog("M68K: Writing to blitter --> %04X at %08X\n", value, address);
216 if ((address >= 0x000000) && (address <= 0x3FFFFE))
218 jaguar_mainRam[address] = value >> 8;
219 jaguar_mainRam[address + 1] = value & 0xFF;
221 else if ((address >= 0xDFFF00) && (address <= 0xDFFFFE))
222 cdrom_word_write(address, value);
223 else if ((address >= 0xF00000) && (address <= 0xF0FFFE))
224 tom_word_write(address, value);
225 else if ((address >= 0xF10000) && (address <= 0xF1FFFE))
226 jerry_word_write(address, value);
228 jaguar_unknown_writeword(address, value);
231 void m68k_write_memory_32(unsigned int address, unsigned int value)
233 extern int dsp_pc;//, dsp_control;
234 if (address == 0xF1A114 && (value & 0x01))
235 WriteLog("M68K(32): DSP is GO! (DSP_PC: %08X)\n", dsp_pc);
237 // WriteLog("M68K(32): DSP halted... (Old value: %08X)\n", dsp_control);
239 //WriteLog( "--> [WM32]\n");
240 m68k_write_memory_16(address, value >> 16);
241 m68k_write_memory_16(address + 2, value & 0xFFFF);
246 uint32 jaguar_get_handler(uint32 i)
248 // return (jaguar_word_read(i<<2) << 16) | jaguar_word_read((i<<2) + 2);
249 // return (jaguar_word_read(i*4) << 16) | jaguar_word_read((i*4) + 2);
250 return jaguar_long_read(i * 4);
253 uint32 jaguar_interrupt_handler_is_valid(uint32 i)
255 uint32 handler = jaguar_get_handler(i);
256 if (handler && (handler != 0xFFFFFFFF))
262 void M68K_show_context(void)
264 WriteLog( "\t68K PC=%06X\n", m68k_get_reg(NULL, M68K_REG_PC));
265 for(int i=M68K_REG_D0; i<=M68K_REG_D7; i++)
266 WriteLog( "\tD%i = %08X\n", i-M68K_REG_D0, m68k_get_reg(NULL, (m68k_register_t)i));
268 for(int i=M68K_REG_A0; i<=M68K_REG_A7; i++)
269 WriteLog( "\tA%i = %08X\n", i-M68K_REG_A0, m68k_get_reg(NULL, (m68k_register_t)i));
271 WriteLog( "68K disasm\n");
272 // jaguar_dasm(s68000readPC()-0x1000,0x20000);
273 jaguar_dasm(m68k_get_reg(NULL, M68K_REG_PC) - 0x80, 0x200);
274 // jaguar_dasm(0x5000, 0x14414);
275 WriteLog( "..................\n");
278 if (tom_irq_enabled(IRQ_VBLANK))
280 WriteLog( "vblank int: enabled\n");
281 jaguar_dasm(jaguar_get_handler(64), 0x200);
284 WriteLog( "vblank int: disabled\n");
285 WriteLog( "..................\n");
287 for(int i=0; i<256; i++)
288 WriteLog( "handler %03i at $%08X\n", i, (unsigned int)jaguar_get_handler(i));
292 // Unknown read/write byte/word routines
295 void jaguar_unknown_writebyte(unsigned address, unsigned data)
297 #ifdef LOG_UNMAPPED_MEMORY_ACCESSES
298 WriteLog( "jaguar: unknown byte %02X write at %08X (PC=%06X)\n", data, address, m68k_get_reg(NULL, M68K_REG_PC));
302 void jaguar_unknown_writeword(unsigned address, unsigned data)
304 #ifdef LOG_UNMAPPED_MEMORY_ACCESSES
305 WriteLog( "jaguar: unknown word %04X write at %08X (PC=%06X)\n", data, address, m68k_get_reg(NULL, M68K_REG_PC));
309 unsigned jaguar_unknown_readbyte(unsigned address)
311 #ifdef LOG_UNMAPPED_MEMORY_ACCESSES
312 WriteLog( "jaguar: unknown byte read at %08X (PC=%06X)\n", address, m68k_get_reg(NULL, M68K_REG_PC));
317 unsigned jaguar_unknown_readword(unsigned address)
319 #ifdef LOG_UNMAPPED_MEMORY_ACCESSES
320 WriteLog( "Jaguar: Unknown word read at %08X (PC=%06X)\n", address, m68k_get_reg(NULL, M68K_REG_PC));
326 // Disassemble M68K instructions at the given offset
329 unsigned int m68k_read_disassembler_8(unsigned int address)
331 return m68k_read_memory_8(address);
334 unsigned int m68k_read_disassembler_16(unsigned int address)
336 return m68k_read_memory_16(address);
339 unsigned int m68k_read_disassembler_32(unsigned int address)
341 return m68k_read_memory_32(address);
344 void jaguar_dasm(uint32 offset, uint32 qt)
347 static char buffer[2048];//, mem[64];
348 int pc = offset, oldpc;
350 for(uint32 i=0; i<qt; i++)
353 // for(int j=0; j<64; j++)
354 // mem[j^0x01] = jaguar_byte_read(pc + j);
356 // pc += Dasm68000((char *)mem, buffer, 0);
357 pc += m68k_disassemble(buffer, pc, M68K_CPU_TYPE_68000);
358 WriteLog("%08X: %s\n", oldpc, buffer);
363 unsigned jaguar_byte_read(unsigned int offset)
368 if (offset < 0x400000)
369 // data = (jaguar_mainRam[(offset^0x01) & 0x3FFFFF]);
370 data = jaguar_mainRam[offset & 0x3FFFFF];
371 else if ((offset >= 0x800000) && (offset < 0xC00000))
372 // data = (jaguar_mainRom[(offset^0x01)-0x800000]);
373 data = jaguar_mainRom[offset - 0x800000];
374 // else if ((offset >= 0xDFFF00) && (offset < 0xDFFF00))
375 else if ((offset >= 0xDFFF00) && (offset <= 0xDFFFFF))
376 data = cdrom_byte_read(offset);
377 else if ((offset >= 0xE00000) && (offset < 0xE40000))
378 // data = (jaguar_bootRom[(offset^0x01) & 0x3FFFF]);
379 data = jaguar_bootRom[offset & 0x3FFFF];
380 else if ((offset >= 0xF00000) && (offset < 0xF10000))
381 data = tom_byte_read(offset);
382 else if ((offset >= 0xF10000) && (offset < 0xF20000))
383 data = jerry_byte_read(offset);
385 data = jaguar_unknown_readbyte(offset);
390 unsigned jaguar_word_read(unsigned int offset)
392 //TEMP--Mirror of F03000?
393 /*if (offset >= 0xF0B000 && offset <= 0xF0BFFF)
394 WriteLog( "[JWR16] --> Possible GPU RAM mirror access! [%08X]\n", offset);//*/
397 if (offset <= 0x3FFFFE)
399 // return (jaguar_mainRam[(offset+1) & 0x3FFFFF] << 8) | jaguar_mainRam[(offset+0) & 0x3FFFFF];
400 return (jaguar_mainRam[(offset+0) & 0x3FFFFF] << 8) | jaguar_mainRam[(offset+1) & 0x3FFFFF];
402 else if ((offset >= 0x800000) && (offset <= 0xBFFFFE))
405 // return (jaguar_mainRom[offset+1] << 8) | jaguar_mainRom[offset+0];
406 return (jaguar_mainRom[offset+0] << 8) | jaguar_mainRom[offset+1];
408 // else if ((offset >= 0xDFFF00) && (offset < 0xDFFF00))
409 else if ((offset >= 0xDFFF00) && (offset <= 0xDFFFFE))
410 return cdrom_word_read(offset);
411 else if ((offset >= 0xE00000) && (offset <= 0xE3FFFE))
412 // return *((uint16 *)&jaguar_bootRom[offset & 0x3FFFF]);
413 return (jaguar_bootRom[(offset+0) & 0x3FFFF] << 8) | jaguar_bootRom[(offset+1) & 0x3FFFF];
414 else if ((offset >= 0xF00000) && (offset <= 0xF0FFFE))
415 return tom_word_read(offset);
416 else if ((offset >= 0xF10000) && (offset <= 0xF1FFFE))
418 //WriteLog("Reading from JERRY offset %08X...\n", offset);
419 return jerry_word_read(offset);
422 return jaguar_unknown_readword(offset);
425 void jaguar_byte_write(unsigned offset, unsigned data)
428 if (offset < 0x400000)
430 // jaguar_mainRam[(offset^0x01) & 0x3FFFFF] = data;
431 jaguar_mainRam[offset & 0x3FFFFF] = data;
434 // else if ((offset >= 0xDFFF00) && (offset < 0xDFFF00))
435 else if ((offset >= 0xDFFF00) && (offset <= 0xDFFFFF))
437 cdrom_byte_write(offset, data);
440 else if ((offset >= 0xF00000) && (offset <= 0xF0FFFF))
442 tom_byte_write(offset, data);
445 else if ((offset >= 0xF10000) && (offset <= 0xF1FFFF))
447 jerry_byte_write(offset, data);
451 jaguar_unknown_writebyte(offset, data);
454 void jaguar_word_write(unsigned offset, unsigned data)
456 extern int dsp_pc;//, dsp_control;
457 if (offset == 0xF1A116 && (data & 0x01))
458 WriteLog(" JagWW: DSP is GO! (DSP_PC: %08X)\n", dsp_pc);
460 // WriteLog("JagWW: DSP halted... (Old value: %08X)\n", dsp_control);
462 //extern int blit_start_log;
463 //if (blit_start_log)
465 if (offset == 0x0674DE)
466 WriteLog( "[JWW16] Bad write starting @ 0674DE! [%04X]\n", data);
468 //TEMP--Mirror of F03000?
469 //if (offset >= 0xF0B000 && offset <= 0xF0BFFF)
470 //WriteLog( "[JWW16] --> Possible GPU RAM mirror access! [%08X]", offset);
471 //if ((offset >= 0x1FF020 && offset <= 0x1FF03F) || (offset >= 0x1FF820 && offset <= 0x1FF83F))
472 // WriteLog("JagWW: Writing %04X at %08X\n", data, offset);
475 if (offset <= 0x3FFFFE)
477 // jaguar_mainRam[(offset+0) & 0x3FFFFF] = data & 0xFF;
478 // jaguar_mainRam[(offset+1) & 0x3FFFFF] = (data>>8) & 0xFF;
479 jaguar_mainRam[(offset+0) & 0x3FFFFF] = (data>>8) & 0xFF;
480 jaguar_mainRam[(offset+1) & 0x3FFFFF] = data & 0xFF;
483 else if ((offset >= 0xDFFF00) && (offset <= 0xDFFFFE))
485 cdrom_word_write(offset, data);
488 else if ((offset >= 0xF00000) && (offset <= 0xF0FFFE))
490 tom_word_write(offset, data);
493 else if ((offset >= 0xF10000) && (offset <= 0xF1FFFE))
495 jerry_word_write(offset, data);
499 jaguar_unknown_writeword(offset, data);
502 unsigned jaguar_long_read(unsigned int offset)
504 /* uint32 data = jaguar_word_read(offset);
505 data = (data<<16) | jaguar_word_read(offset+2);
507 return (jaguar_word_read(offset) << 16) | jaguar_word_read(offset+2);
510 void jaguar_long_write(unsigned offset, unsigned data)
512 extern int dsp_pc;//, dsp_control;
513 if (offset == 0xF1A114 && (data & 0x01))
514 WriteLog("JagLW: DSP is GO! (DSP_PC: %08X)\n", dsp_pc);
516 // WriteLog("JagLW: DSP halted... (Old value: %08X)\n", dsp_control);
518 //extern int effect_start;
519 // $10, $0C, $0A, $09 too much, $08 too little...
520 //if (effect_start && offset == 0xF03000) data = (data & 0xFFFF0000) | (((data & 0xFFFF) + 0x0008) & 0xFFFF);
521 //Doesn't work--offsets horizontally if (effect_start && offset == 0xF03004) data -= (0x300 * 8); // one line is $300
522 //if (effect_start && offset == 0xF03000) data = 0x00000000; // Let's try making the top/bottom *always* 0!
523 //Interesting: it seems to pin half of the screen down (but too low)...
524 //Definitely the fine scroll offsets (for left side of screen)...
526 //if ((offset >= 0x1FF020 && offset <= 0x1FF03F) || (offset >= 0x1FF820 && offset <= 0x1FF83F))
527 // WriteLog("JagLW: Writing %08X at %08X\n", data, offset);
528 jaguar_word_write(offset, data >> 16);
529 jaguar_word_write(offset+2, data & 0xFFFF);
533 // Jaguar initialization
536 //void jaguar_init(const char * filename)
537 void jaguar_init(void)
541 jaguar_screen_scanlines = 525; // PAL screen size
542 m68k_cycles_per_scanline = 13300000 / (jaguar_screen_scanlines * 60);
543 gpu_cycles_per_scanline = (26591000 / 4) / (jaguar_screen_scanlines * 60);
544 dsp_cycles_per_scanline = (26591000 / 4) / (jaguar_screen_scanlines * 60);
546 memory_malloc_secure((void **)&jaguar_mainRam, 0x400000, "Jaguar 68K CPU RAM");
547 memory_malloc_secure((void **)&jaguar_bootRom, 0x040000, "Jaguar 68K CPU BIOS ROM");
548 memory_malloc_secure((void **)&jaguar_mainRom, 0x600000, "Jaguar 68K CPU ROM");
549 memset(jaguar_mainRam, 0x00, 0x400000);
550 // memset(jaguar_mainRom, 0xFF, 0x200000); // & set it to all Fs...
551 memset(jaguar_mainRom, 0x00, 0x200000); // & set it to all 0s...
553 // jaguar_rom_load_to(jaguar_bootRom, jaguar_bootRom_path, &romsize);
554 // memcpy(jaguar_mainRam, jaguar_bootRom, 8);
555 // SET32(jaguar_mainRam, 0, 0x00200000);
557 #ifdef JAGUAR_WIP_RELEASE
558 // strcpy(romLoadDialog_filePath, filename);
559 // jaguar_load_cart(romLoadDialog_filePath, jaguar_mainRom, 0x0000, 0x00802000, 0);
561 if ((jaguar_mainRom_crc32 == 0x3966698f) || (jaguar_mainRom_crc32 == 0x5e705756)
562 || (jaguar_mainRom_crc32 == 0x2630cbc4) || (jaguar_mainRom_crc32 == 0xd46437e8)
563 || (jaguar_mainRom_crc32 == 0x2630cbc4))
566 if ((jaguar_mainRom_crc32 == 0x6e90989f) || (jaguar_mainRom_crc32 == 0xfc8f0dcd)
567 || (jaguar_mainRom_crc32 == 0x2a512a83) || (jaguar_mainRom_crc32 == 0x41307601)
568 || (jaguar_mainRom_crc32 == 0x3c7bfda8) || (jaguar_mainRom_crc32 == 0x5e705756))
569 gpu_cycles_per_scanline = (26591000 / 1) / (jaguar_screen_scanlines * 60);
571 if (jaguar_mainRom_crc32 == 0x7ae20823)
574 gpu_cycles_per_scanline = (26591000 / 1) / (jaguar_screen_scanlines * 60);
575 dsp_cycles_per_scanline = (26591000 / 1) / (jaguar_screen_scanlines * 60);
577 if (jaguar_mainRom_crc32 == 0xe21d0e2f)
580 gpu_cycles_per_scanline = (26591000 / 1) / (jaguar_screen_scanlines * 60);
581 dsp_cycles_per_scanline = (26591000 / 1) / (jaguar_screen_scanlines * 60);
583 if (jaguar_mainRom_crc32 == 0x66f8914c)
585 gpu_cycles_per_scanline = (26591000 / 1) /(jaguar_screen_scanlines * 60);
587 if (jaguar_mainRom_crc32 == 0x5a5b9c68)
589 gpu_cycles_per_scanline = (26591000 / 1) / (jaguar_screen_scanlines * 60);
591 if (jaguar_mainRom_crc32 == 0xdcb0197a)
593 dsp_enabled = false; // dsp not needed
594 gpu_cycles_per_scanline = (26591000 / 1) / (jaguar_screen_scanlines * 60);
595 //dsp_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60);
597 if ((jaguar_mainRom_crc32 == 0x3966698f) || (jaguar_mainRom_crc32 == 0xe21d0e2f))
599 if (jaguar_mainRom_crc32 == 0x5e705756)
601 gpu_cycles_per_scanline = (26591000 / 1) / (jaguar_screen_scanlines * 60);
604 if (jaguar_mainRom_crc32 == 0x2630cbc4)
607 gpu_cycles_per_scanline = (26591000 / 1) / (jaguar_screen_scanlines * 60);
608 dsp_cycles_per_scanline = (26591000 / 1) / (jaguar_screen_scanlines * 60);
611 if ((jaguar_mainRom_crc32 == 0xd46437e8) || (jaguar_mainRom_crc32 == 0xba74c3ed))
613 gpu_cycles_per_scanline = (26591000 / 1) / (jaguar_screen_scanlines * 60);
616 if (jaguar_mainRom_crc32 == 0x6e90989f)
617 gpu_cycles_per_scanline = (26591000 / 1) / (jaguar_screen_scanlines * 60);
619 if (jaguar_mainRom_crc32 == 0x41307601)
621 gpu_cycles_per_scanline = (26591000 / 1) / (jaguar_screen_scanlines * 60);
624 if (jaguar_mainRom_crc32 == 0x8483392b)
629 #else // #ifdef JAGUAR_WIP_RELEASE
630 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/flashback.jag",jaguar_mainRom,0x0000, 0x20000080,0);
631 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/Pinball Fantasies.JAG",jaguar_mainRom,0x0000, 0x20000080,0);
632 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/alien vs predator (1994).jag",jaguar_mainRom,0x0000, 0x20000080,0);
633 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/cannon fodder (1995) (computer west).jag",jaguar_mainRom,0x0000, 0x20000080,0);
634 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/double dragon v (1995) (williams).jag",jaguar_mainRom,0x0000, 0x20000080,0);
635 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/Dragon - The Bruce Lee Story.JAG",jaguar_mainRom,0x0000, 0x20000080,0);
636 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/Syndicate.JAG",jaguar_mainRom,0x0000, 0x20000080,0);
637 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/Theme Park.JAG",jaguar_mainRom,0x0000, 0x20000080,0);
638 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/Brutal Sports Football.JAG",jaguar_mainRom,0x0000, 0x20000080,0);
639 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/International Sensible Soccer.JAG",jaguar_mainRom,0x0000, 0x20000080,0);
640 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/Defender 2000.JAG",jaguar_mainRom,0x0000, 0x20000080,0);
641 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/Fever Pitch Soccer.JAG",jaguar_mainRom,0x0000, 0x20000080,0);
642 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/Rayman.JAG",jaguar_mainRom,0x0000, 0x20000080,0);
643 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/Tempest 2000.JAG",jaguar_mainRom,0x0000, 0x20000080,0);
644 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/zool 2 (1994).jag",jaguar_mainRom,0x0000, 0x20000080,0);
645 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/Bubsy - Fractured Furry Tails.JAG",jaguar_mainRom,0x0000, 0x20000080,0);
646 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/Raiden.JAG",jaguar_mainRom,0x0000, 0x20000080,0);
647 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/Dino Olympics.jag",jaguar_mainRom,0x0000, 0x20000080,0);
648 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/I-War.jag",jaguar_mainRom,0x0000, 0x20000080,0);
649 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/Attack of the Mutant Penguins.JAG",jaguar_mainRom,0x0000, 0x20000080,0);
650 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/Cybermorph.jag",jaguar_mainRom,0x0000, 0x20000080,0);
651 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/Troy Aikman NFL Football (1995) (Williams).jag",jaguar_mainRom,0x0000, 0x20000080,0);
652 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/Power Drive Rally (1995) (TWI).jag",jaguar_mainRom,0x0000, 0x20000080,0);
653 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/Zoop! (1996).jag",jaguar_mainRom,0x0000, 0x20000080,0);
654 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/Missile Command 3D.JAG",jaguar_mainRom,0x0000, 0x20000080,0);
655 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/Hover Strike.jag",jaguar_mainRom,0x0000, 0x20000080,0);
656 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/worms.bin",jaguar_mainRom,0x0000, 0x20000080,0);
657 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/Atari Kart.JAG",jaguar_mainRom,0x0000, 0x20000080,0);
658 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/native.bin",jaguar_mainRam,0x5000, 0x50000000,0x00);
660 if (jaguar_mainRom_crc32==0xe21d0e2f)
663 gpu_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60);
664 dsp_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60);
666 if (jaguar_mainRom_crc32==0x66f8914c)
668 gpu_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60);
670 if (jaguar_mainRom_crc32==0x5a5b9c68)
672 gpu_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60);
674 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/Super Cross 3D.JAG",jaguar_mainRom,0x0000, 0x20000080,0);
675 if (jaguar_mainRom_crc32==0xdcb0197a)
677 dsp_enabled=true; // dsp not needed
678 gpu_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60);
679 //dsp_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60);
681 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/wolfenstein 3d (1994).jag",jaguar_mainRom,0x0000, 0x20000080,0);
682 if ((jaguar_mainRom_crc32==0x3966698f)||(jaguar_mainRom_crc32==0xe21d0e2f))
684 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/NBA JAM.jag",jaguar_mainRom,0x0000, 0x20000080,0);
685 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/Doom - Evil Unleashed.JAG",jaguar_mainRom,0x0000, 0x20000080,0);
686 if (jaguar_mainRom_crc32==0x5e705756)
688 gpu_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60);
691 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/Ultra Vortek.JAG",jaguar_mainRom,0x0000, 0x20000080,0);
692 if (jaguar_mainRom_crc32==0x2630cbc4)
695 gpu_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60);
696 dsp_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60);
699 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/fflbeta.rom",jaguar_mainRom,0x0000, 0x20000080,0);
700 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/Fight for Your Life.jag",jaguar_mainRom,0x0000, 0x20000080,0);
701 if ((jaguar_mainRom_crc32==0xd46437e8)||(jaguar_mainRom_crc32==0xba74c3ed))
703 gpu_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60);
704 // dsp_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60);
707 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/Pitfall - The Mayan Adventure.JAG",jaguar_mainRom,0x0000, 0x20000080,0);
708 if (jaguar_mainRom_crc32==0x6e90989f)
709 gpu_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60);
711 // missing some sprites
712 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/Crescent Galaxy.jag",jaguar_mainRom,0x0000, 0x20000080,0);
713 if (jaguar_mainRom_crc32==0x41307601)
715 gpu_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60);
718 // missing vertical bar shades
719 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/Phase Zero (2000) (PD).rom",jaguar_mainRom,0x0000, 0x20000080,0);
720 if (jaguar_mainRom_crc32==0x8483392b)
724 // cpu/dsp/gpu synchronization problems
727 // locks up during the game
728 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/Club Drive.JAG",jaguar_mainRom,0x0000, 0x20000080,0);
730 // no parallax floor, locks up at the start of the game
731 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/Kasumi Ninja.JAG",jaguar_mainRom,0x0000, 0x20000080,0);
733 // displaying the sound control dialog. no way to exit from it
734 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/Checkered Flag.JAG",jaguar_mainRom,0x0000, 0x20000080,0);
737 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/Iron Soldier.jag",jaguar_mainRom,0x0000, 0x20000080,0);
739 // locks up at the start of the game
740 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/Super Burnout.JAG",jaguar_mainRom,0x0000, 0x20000080,0);
741 if (jaguar_mainRom_crc32==0x20ae75f4)
744 gpu_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60);
745 dsp_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60);
747 // locks up at the start of the game
748 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/Val D'Isere Skiing & Snowboarding (1994).jag",jaguar_mainRom,0x0000, 0x20000080,0);
749 if (jaguar_mainRom_crc32==0x4664ebd1)
754 // fonctionne avec le gpu et le dsp activés et gpu à frequence nominale, et dsp à 1/4 de la frequence nominale
755 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/white men can't jump (1995).jag",jaguar_mainRom,0x0000, 0x20000080,0);
756 if (jaguar_mainRom_crc32==0x7ae20823)
759 gpu_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60);
761 // not working at all
762 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/Flip Out.JAG",jaguar_mainRom,0x0000, 0x20000080,0);
763 if (jaguar_mainRom_crc32==0x6f57dcd2)
765 gpu_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60);
770 jaguar_load_cart("C:/ftp/jaguar/roms/roms/Ruiner.JAG",jaguar_mainRom,0x0000, 0x20000080,0);
771 if (jaguar_mainRom_crc32==0x6a7c7430)
776 if (jaguar_mainRom_crc32==0x2f032271)
779 dsp_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60);
780 gpu_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60);
782 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/tetris.bin",jaguar_mainRam,0x4fe4, 0x50000000,0x00);
783 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/painter.bin",jaguar_mainRam,0xffe4, 0x00000001,0x00);
784 // jaguar_load_cart("./roms/jagcd.rom",jaguar_mainRom,0x0000, 0x20000080,0);
786 // jaguar_load_cart("cart.jag",jaguar_mainRom,0x0000, 0x20000080,0);
789 // cd_bios_boot("C:\\ftp\\jaguar\\cd\\Brain Dead 13.cdi");
790 // cd_bios_boot("C:\\ftp\\jaguar\\cd\\baldies.cdi");
791 // cd_bios_boot("C:\\ftp\\jaguar\\cd\\mystdemo.cdi");
792 // cd_bios_boot("C:\\ftp\\jaguar\\cd\\battlemorph.cdi");
793 // cd_bios_boot("C:\\ftp\\jaguar\\cd\\primalrage.cdi");
794 // cd_bios_boot("C:\\ftp\\jaguar\\cd\\Dragons Lair.cdi");
796 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/raw.jag",jaguar_mainRam,0x4000, 0x40000000,0x00);
797 #endif // #ifdef JAGUAR_WIP_RELEASE
799 #ifdef JAGUAR_REAL_SPEED
800 gpu_cycles_per_scanline = (26591000 / 1) / (jaguar_screen_scanlines * 60);
801 dsp_cycles_per_scanline = (26591000 / 1) / (jaguar_screen_scanlines * 60);
807 m68k_set_cpu_type(M68K_CPU_TYPE_68000);
815 void jaguar_done(void)
818 // for(int i=M68K_REG_A0; i<=M68K_REG_A7; i++)
819 // WriteLog("\tA%i = 0x%.8x\n", i-M68K_REG_A0, m68k_get_reg(NULL, (m68k_register_t)i));
820 uint32 topOfStack = m68k_get_reg(NULL, M68K_REG_A7);
821 WriteLog("M68K: Top of stack: %08X. Stack trace:\n", jaguar_long_read(topOfStack));
822 for(int i=0; i<10; i++)
823 WriteLog("%06X: %08X\n", topOfStack - (i * 4), jaguar_long_read(topOfStack - (i * 4)));
824 // WriteLog("Jaguar: CD BIOS version %04X\n", jaguar_word_read(0x3004));
825 WriteLog("Jaguar: VBL interrupt is %s\n", ((tom_irq_enabled(IRQ_VBLANK)) && (jaguar_interrupt_handler_is_valid(64))) ? "enabled" : "disabled");
835 memory_free(jaguar_mainRom);
836 memory_free(jaguar_bootRom);
837 memory_free(jaguar_mainRam);
840 void jaguar_reset(void)
843 memcpy(jaguar_mainRam, jaguar_bootRom, 8);
846 SET32(jaguar_mainRam, 4, 0x00802000);
847 // Handle PD stuff...
848 // This should definitely go elsewhere (like in the cart load section)!
849 if (jaguar_mainRom[0] == 0x60 && jaguar_mainRom[1] == 0x1A)
851 uint32 runAddress = GET32(jaguar_mainRom, 0x2A);
852 uint32 progLength = GET32(jaguar_mainRom, 0x02);
853 WriteLog("Setting up PD ROM... Run address: %08X, length: %08X\n", runAddress, progLength);
854 memcpy(jaguar_mainRam + runAddress, jaguar_mainRom + 0x2E, progLength);
855 SET32(jaguar_mainRam, 4, runAddress);
859 // WriteLog("jaguar_reset():\n");
869 m68k_pulse_reset(); // Reset the 68000
870 WriteLog( "\t68K PC=%06X SP=%08X\n", m68k_get_reg(NULL, M68K_REG_PC), m68k_get_reg(NULL, M68K_REG_A7));
873 void jaguar_reset_handler(void)
877 void jaguar_exec(int16 * backbuffer, bool render)
879 uint32 i, vblank_duration = tom_get_vdb();
882 if ((tom_irq_enabled(IRQ_VBLANK)) && (jaguar_interrupt_handler_is_valid(64)))
884 if (jaguar_word_read(0xF0004E) != 0xFFFF)
886 tom_set_pending_video_int();
887 // s68000interrupt(7, IRQ_VBLANK+64);
888 // s68000flushInterrupts();
889 m68k_set_irq(7); // IRQ_VBLANK+64??? Not autovectored??? No.
890 // Could set a global variable here, to signal that this is a VBLANK interrupt...
891 // Then again, since IRQ_VBLANK is set to zero, this would not be necessary in this case.
895 for(i=0; i<vblank_duration; i++)
897 /* uint32 invalid_instruction_address = s68000exec(m68k_cycles_per_scanline);
898 if (invalid_instruction_address != 0x80000000)
899 cd_bios_process(invalid_instruction_address);*/
900 m68k_execute(m68k_cycles_per_scanline);
901 // No CD handling... !!! FIX !!!
904 tom_pit_exec(m68k_cycles_per_scanline);
905 tom_exec_scanline(backbuffer, i, false);
906 jerry_pit_exec(m68k_cycles_per_scanline);
907 jerry_i2s_exec(m68k_cycles_per_scanline);
908 gpu_exec(gpu_cycles_per_scanline);
910 dsp_exec(dsp_cycles_per_scanline);
913 for (; i<jaguar_screen_scanlines; i++)
915 /* uint32 invalid_instruction_address = s68000exec(m68k_cycles_per_scanline);
916 if (invalid_instruction_address != 0x80000000)
917 cd_bios_process(invalid_instruction_address);*/
918 m68k_execute(m68k_cycles_per_scanline);
919 // No CD handling... !!! FIX !!!
921 tom_pit_exec(m68k_cycles_per_scanline);
922 jerry_pit_exec(m68k_cycles_per_scanline);
923 jerry_i2s_exec(m68k_cycles_per_scanline);
924 tom_exec_scanline(backbuffer, i, render);
925 gpu_exec(gpu_cycles_per_scanline);
927 dsp_exec(dsp_cycles_per_scanline);
928 backbuffer += tom_width;
931 system_sound_update();
935 // Temp debugging stuff
937 void DumpMainMemory(void)
939 FILE * fp = fopen("./memdump.bin", "wb");
944 fwrite(jaguar_mainRam, 1, 0x400000, fp);
948 uint8 * GetRamPtr(void)
950 return jaguar_mainRam;