]> Shamusworld >> Repos - virtualjaguar/blob - src/jaguar.cpp
Virtual Jaguar GCC/SDL v1.0.3 import.
[virtualjaguar] / src / jaguar.cpp
1 //
2 // JAGUAR.CPP
3 //
4 // by cal2
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. :-)
9 // 
10
11 #include "jaguar.h"
12 #include "m68kdasmAG.h"
13 #include "crc32.h"
14
15 //#define LOG_UNMAPPED_MEMORY_ACCESSES
16 //#define SOUND_OUTPUT
17
18 // Some handy macros to help converting native endian to big endian (jaguar native)
19
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
22
23 //
24 // Function Prototypes
25 //
26
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
32
33 #ifdef SOUND_OUTPUT
34 int dsp_enabled = 1;
35 #else
36 int dsp_enabled = 0;
37 #endif
38 uint32 jaguar_active_memory_dumps = 0;
39 uint32 jaguar_use_bios = 0;
40 #define JAGUAR_WIP_RELEASE
41 #define JAGUAR_REAL_SPEED
42
43 //
44 // Bios path
45 //
46
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/";
51
52 uint32 jaguar_mainRom_crc32;
53
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;
58
59 static uint8 * jaguar_mainRam = NULL;
60 static uint8 * jaguar_bootRom = NULL;
61 static uint8 * jaguar_mainRom = NULL;
62
63
64 //
65 // Musashi 68000 read/write/IRQ functions
66 //
67
68 int irq_ack_handler(int level)
69 {
70         int vector = M68K_INT_ACK_AUTOVECTOR;
71
72         if (level = 7)
73         {
74                 m68k_set_irq(0);                                                // Clear the IRQ...
75                 vector = 64;                                                    // Set user interrupt #0
76         }
77
78         return vector;
79 }
80
81 //Do this in makefile??? Yes!
82 //#define LOG_UNMAPPED_MEMORY_ACCESSES 1
83
84 unsigned int m68k_read_memory_8(unsigned int address)
85 {
86 //fprintf(log_get(), "[RM8] Addr: %08X\n", address);
87         unsigned int retVal = 0;
88
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);
101         else
102                 retVal = jaguar_unknown_readbyte(address);
103
104     return retVal;
105 }
106
107 unsigned int m68k_read_memory_16(unsigned int address)
108 {
109 //fprintf(log_get(), "[RM16] Addr: %08X\n", address);
110     unsigned int retVal = 0;
111
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);
124         else
125 //{
126 //fprintf(log_get(), "[RM16] Unknown address: %08X\n", address);
127                 retVal = jaguar_unknown_readword(address);
128 //}
129
130     return retVal;
131 }
132
133 unsigned int m68k_read_memory_32(unsigned int address)
134 {
135 //fprintf(log_get(), "--> [RM32]\n");
136     return (m68k_read_memory_16(address) << 16) | m68k_read_memory_16(address + 2);
137 }
138
139 void m68k_write_memory_8(unsigned int address, unsigned int value)
140 {
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);
150         else
151                 jaguar_unknown_writebyte(address, value);
152 }
153
154 void m68k_write_memory_16(unsigned int address, unsigned int value)
155 {
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))
158         {
159                 jaguar_mainRam[address] = value >> 8;
160                 jaguar_mainRam[address + 1] = value & 0xFF;
161         }
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);
168         else
169                 jaguar_unknown_writeword(address, value);
170 }
171
172 void m68k_write_memory_32(unsigned int address, unsigned int value)
173 {
174 //fprintf(log_get(), "--> [WM32]\n");
175         m68k_write_memory_16(address, value >> 16);
176         m68k_write_memory_16(address + 2, value & 0xFFFF);
177 }
178
179
180 //////////////////////////////////////////////////////////////////////////////
181 //
182 //////////////////////////////////////////////////////////////////////////////
183 //
184 //
185 //
186 //////////////////////////////////////////////////////////////////////////////
187 uint32 jaguar_get_handler(uint32 i)
188 {
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);
192 }
193
194 //////////////////////////////////////////////////////////////////////////////
195 //
196 //////////////////////////////////////////////////////////////////////////////
197 //
198 //
199 //
200 //
201 //
202 //////////////////////////////////////////////////////////////////////////////
203 static char romLoadDialog_filePath[1024];
204 #ifndef __PORT__
205 static char romLoadDialog_initialDirectory[1024];
206
207 int jaguar_open_rom(HWND hWnd, char * title, char * filterString)
208 {
209         OPENFILENAME ofn;
210         romLoadDialog_initialDirectory[0] = 0;
211         romLoadDialog_filePath[0] = 0;
212
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;
225
226         if(GetOpenFileName(&ofn) == FALSE) 
227         {
228                 DWORD res = CommDlgExtendedError();
229                 SendMessage(hWnd, WM_MOVE, 0,0);
230                 return 0;
231         }
232
233
234         SendMessage(hWnd, WM_MOVE, 0,0);
235         return 1;
236 }
237 #endif
238 //////////////////////////////////////////////////////////////////////////////
239 //
240 //////////////////////////////////////////////////////////////////////////////
241 //
242 //
243 //
244 //////////////////////////////////////////////////////////////////////////////
245 uint32 jaguar_interrupt_handler_is_valid(uint32 i)
246 {
247         uint32 handler = jaguar_get_handler(i);
248         if (handler && (handler != 0xFFFFFFFF))
249                 return 1;
250         else
251                 return 0;
252 }
253 //////////////////////////////////////////////////////////////////////////////
254 //
255 //////////////////////////////////////////////////////////////////////////////
256 //
257 //
258 //
259 //////////////////////////////////////////////////////////////////////////////
260 void s68000show_context(void)
261 {
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");
269 //      for (i=0;i<8;i++)
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));
273
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");
279
280
281         if (tom_irq_enabled(IRQ_VBLANK))
282         {
283                 fprintf(log_get(), "vblank int: enabled\n");
284                 jaguar_dasm(jaguar_get_handler(64), 0x200);
285         }
286         else
287                 fprintf(log_get(), "vblank int: disabled\n");
288         fprintf(log_get(), "..................\n");
289
290         for(int i=0; i<256; i++)
291                 fprintf(log_get(), "handler %03i at $%08X\n", i, jaguar_get_handler(i));
292 }
293
294 // Starscream crap ripped out...
295
296 //
297 // Unknown read/write byte/word routines
298 //
299
300 void jaguar_unknown_writebyte(unsigned address, unsigned data)
301 {
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));
304 #endif
305 }
306
307 void jaguar_unknown_writeword(unsigned address, unsigned data)
308 {
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));
311 #endif
312 }
313
314 unsigned jaguar_unknown_readbyte(unsigned address)
315 {
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));
318 #endif
319     return 0xFF;
320 }
321
322 unsigned jaguar_unknown_readword(unsigned address)
323 {
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));
326 #endif
327     return 0xFFFF;
328 }
329
330 //
331 // Jaguar ROM loading
332 //
333
334 uint8 * jaguar_rom_load(char * path, uint32 * romSize)
335 {
336         __int64 filepos;
337
338         fprintf(log_get(), "jaguar: loading %s...", path);
339         FILE * fp = fopen(path, "rb");
340         if (fp == NULL)
341         {
342                 fprintf(log_get(), "failed\n");
343                 log_done();
344                 exit(0);
345                 return NULL;
346         }
347         fseek(fp, 0, SEEK_END);
348
349         /* Added by SDLEMU (http://sdlemu.ngemu.com) */
350         /* Added for GCC UNIX compatibility          */
351 #ifdef __GCCUNIX__
352         fgetpos(fp, (fpos_t *)&filepos);
353 #else
354         fgetpos(fp, &filepos);
355 #endif
356         
357         *romSize = (int)filepos;
358         fseek(fp, 0, SEEK_SET);
359         uint8 * rom = (uint8 *)malloc(*romSize);
360         fread(rom, 1, *romSize, fp);
361         fclose(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);
365         return rom;
366 }
367
368 //
369 // Load a ROM at a specific address
370 //
371
372 void jaguar_rom_load_to(uint8 * rom, char * path, uint32 * romSize)
373 {
374         __int64 filepos;
375
376         fprintf(log_get(), "jaguar: loading %s...", path);
377         FILE * fp = fopen(path, "rb");
378         if (fp == NULL)
379         {
380                 fprintf(log_get(), "failed\n");
381                 log_done();
382                 exit(0);
383                 return;
384         }
385         fseek(fp, 0, SEEK_END);
386
387         /* Added by SDLEMU (http://sdlemu.ngemu.com) */
388         /* Added for GCC UNIX compatibility          */
389 #ifdef __GCCUNIX__
390         fgetpos(fp, (fpos_t *)&filepos);
391 #else
392         fgetpos(fp, &filepos);
393 #endif
394
395         *romSize = (int)filepos;
396         fseek(fp, 0, SEEK_SET);
397         fread(rom, 1, *romSize, fp);
398         fclose(fp);
399         fprintf(log_get(), "ok (%i bytes)\n", *romSize);
400 }
401
402 //
403 // Byte swap a region of memory
404 //
405
406 /*void jaguar_byte_swap(uint8 * rom, uint32 size)
407 {
408         while (size > 0)
409         {
410                 uint8 tmp = rom[0];
411                 rom[0] = rom[1];
412                 rom[1] = tmp;
413                 rom += 2;
414                 size -= 2;
415         }
416 }*/
417
418 //
419 // Disassemble instructions at the given offset
420 //
421
422 void jaguar_dasm(uint32 offset, uint32 qt)
423 {
424 #ifdef CPU_DEBUG
425         static char buffer[2048], mem[64];
426         int pc = offset, oldpc;
427
428         for(int i=0; i<qt; i++)
429         {
430                 oldpc = pc;
431                 for(int j=0; j<64; j++)
432                         mem[j^0x01] = jaguar_byte_read(pc + j);
433
434                 pc += Dasm68000((char *)mem, buffer, 0);
435                 fprintf(log_get(), "%08X: %s\n", oldpc, buffer);
436         }
437 #endif
438 }
439
440 //
441 // Jaguar cartridge ROM loading
442 //
443
444 void jaguar_load_cart(char * path, uint8 * mem, uint32 offs, uint32 boot, uint32 header)
445 {
446         uint32 romsize;
447
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);
453
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);
458 // Same as above...
459 //      jaguar_dasm((boot>>16) | (boot<<16), 32*4);
460         jaguar_dasm(boot, 32*4);
461 }
462
463 //
464 // Jaguar initialization
465 //
466
467 #ifdef __PORT__
468 void jaguar_init(const char * filename)
469 #else
470 void jaguar_init(void)
471 #endif
472 {
473         uint32 romsize;
474
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);
479
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);
484
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);
492
493 #ifdef JAGUAR_WIP_RELEASE
494 #ifdef __PORT__
495         strcpy(romLoadDialog_filePath, filename);
496 #else
497         jaguar_open_rom(GetForegroundWindow(), "Load", "Jaguar roms (*.JAG)\0*.JAG\0\0");
498 #endif
499 //WAS:  jaguar_load_cart(romLoadDialog_filePath, jaguar_mainRom, 0x0000, 0x20000080, 0);
500         jaguar_load_cart(romLoadDialog_filePath, jaguar_mainRom, 0x0000, 0x00802000, 0);
501
502 //JLH:
503 /*      if (jaguar_mainRom_crc32 == 0xA9F8A00E)
504         {
505                 dsp_enabled = 1;
506                 fprintf(log_get(), "--> Rayman detected, DSP enabled...\n");
507         }//*/
508
509
510         if ((jaguar_mainRom_crc32 == 0x3966698f) || (jaguar_mainRom_crc32 == 0x5e705756)
511                 || (jaguar_mainRom_crc32 == 0x2630cbc4) || (jaguar_mainRom_crc32 == 0xd46437e8)
512                 || (jaguar_mainRom_crc32 == 0x2630cbc4))
513                 dsp_enabled = 1;
514
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);
519
520         if (jaguar_mainRom_crc32 == 0x7ae20823)
521         {
522                 dsp_enabled = 1;
523                 gpu_cycles_per_scanline = (26591000 / 1) / (jaguar_screen_scanlines * 60);
524                 dsp_cycles_per_scanline = (26591000 / 1) / (jaguar_screen_scanlines * 60);
525         }
526         if (jaguar_mainRom_crc32 == 0xe21d0e2f)
527         {
528                 dsp_enabled = 1;
529                 gpu_cycles_per_scanline = (26591000 / 1) / (jaguar_screen_scanlines * 60);
530                 dsp_cycles_per_scanline = (26591000 / 1) / (jaguar_screen_scanlines * 60);
531         }
532         if (jaguar_mainRom_crc32 == 0x66f8914c)
533         {
534                 gpu_cycles_per_scanline = (26591000 / 1) /(jaguar_screen_scanlines * 60);
535         }
536         if (jaguar_mainRom_crc32 == 0x5a5b9c68)
537         {
538                 gpu_cycles_per_scanline = (26591000 / 1) / (jaguar_screen_scanlines * 60);
539         }
540         if (jaguar_mainRom_crc32 == 0xdcb0197a)
541         {
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);
545         }
546         if ((jaguar_mainRom_crc32 == 0x3966698f) || (jaguar_mainRom_crc32 == 0xe21d0e2f))
547                 dsp_enabled = 1;
548         if (jaguar_mainRom_crc32 == 0x5e705756)
549         {
550                 gpu_cycles_per_scanline = (26591000 / 1) / (jaguar_screen_scanlines * 60);
551                 dsp_enabled = 1;
552         }
553         if (jaguar_mainRom_crc32 == 0x2630cbc4)
554         {
555                 // ultra vortek
556                 gpu_cycles_per_scanline = (26591000 / 1) / (jaguar_screen_scanlines * 60);
557                 dsp_cycles_per_scanline = (26591000 / 1) / (jaguar_screen_scanlines * 60);
558                 dsp_enabled = 1;
559         }
560         if ((jaguar_mainRom_crc32 == 0xd46437e8) || (jaguar_mainRom_crc32 == 0xba74c3ed))
561         {
562                 gpu_cycles_per_scanline = (26591000 / 1) / (jaguar_screen_scanlines * 60);
563                 dsp_enabled = 1;
564         }
565         if (jaguar_mainRom_crc32 == 0x6e90989f)
566                 gpu_cycles_per_scanline = (26591000 / 1) / (jaguar_screen_scanlines * 60);
567
568         if (jaguar_mainRom_crc32 == 0x41307601)
569         {
570                 gpu_cycles_per_scanline = (26591000 / 1) / (jaguar_screen_scanlines * 60);
571         }
572
573         if (jaguar_mainRom_crc32 == 0x8483392b)
574         {
575                 dsp_enabled = 1;
576         }
577
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);
608
609         if (jaguar_mainRom_crc32==0xe21d0e2f)
610         {
611                 dsp_enabled=1;
612                 gpu_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60);
613                 dsp_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60);
614         }
615         if (jaguar_mainRom_crc32==0x66f8914c)
616         {
617                 gpu_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60);
618         }
619         if (jaguar_mainRom_crc32==0x5a5b9c68)
620         {
621                 gpu_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60);
622         }
623 //      jaguar_load_cart("C:/ftp/jaguar/roms/roms/Super Cross 3D.JAG",jaguar_mainRom,0x0000, 0x20000080,0);
624         if (jaguar_mainRom_crc32==0xdcb0197a)
625         {
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);
629         }
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))
632                 dsp_enabled=1;
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)
636         {
637                 gpu_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60);
638                 dsp_enabled=1;
639         }
640 //      jaguar_load_cart("C:/ftp/jaguar/roms/roms/Ultra Vortek.JAG",jaguar_mainRom,0x0000, 0x20000080,0);
641         if (jaguar_mainRom_crc32==0x2630cbc4)
642         {
643                 // ultra vortek
644                 gpu_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60);
645                 dsp_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60);
646                 dsp_enabled=1; 
647         }
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))
651         {
652                 gpu_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60);
653 //              dsp_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60);
654                 dsp_enabled=1;
655         }
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);
659
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)
663         {
664                 gpu_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60);
665         }
666
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)
670         {
671                 dsp_enabled=1;
672         }
673 // cpu/dsp/gpu synchronization problems
674
675
676 // locks up during the game
677 //      jaguar_load_cart("C:/ftp/jaguar/roms/roms/Club Drive.JAG",jaguar_mainRom,0x0000, 0x20000080,0);
678
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);
681
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);
684
685 // no 3d        
686 //  jaguar_load_cart("C:/ftp/jaguar/roms/roms/Iron Soldier.jag",jaguar_mainRom,0x0000, 0x20000080,0);
687
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)
691         {
692                 dsp_enabled=1;
693                 gpu_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60);
694                 dsp_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60);
695         }
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)
699         {
700                 dsp_enabled=1;
701         }
702
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)
706         {
707                 dsp_enabled=1;
708                 gpu_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60);
709         }
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)
713         {
714                 gpu_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60);
715                 dsp_enabled=0;
716
717         }
718
719         jaguar_load_cart("C:/ftp/jaguar/roms/roms/Ruiner.JAG",jaguar_mainRom,0x0000, 0x20000080,0);
720         if (jaguar_mainRom_crc32==0x6a7c7430)
721         {
722                 dsp_enabled=1;
723         }
724
725         if (jaguar_mainRom_crc32==0x2f032271)
726         {
727                 dsp_enabled=1;
728                 dsp_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60);
729                 gpu_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60);
730         }
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);
734
735 //      jaguar_load_cart("cart.jag",jaguar_mainRom,0x0000, 0x20000080,0);
736
737         
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");
744
745 //      jaguar_load_cart("C:/ftp/jaguar/roms/roms/raw.jag",jaguar_mainRam,0x4000, 0x40000000,0x00);
746 #endif  // #ifdef JAGUAR_WIP_RELEASE
747
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);
751 #endif
752 #ifdef SOUND_OUTPUT
753         ws_audio_init();
754 #endif
755         if (jaguar_use_bios)
756         {
757                 memcpy(jaguar_mainRam, jaguar_bootRom, 8);
758 //              *((uint32 *)&jaguar_mainRam[0]) = 0x00000020;
759 //              SET32(jaguar_mainRam, 0, 0x00200000);
760         }
761
762 //      s68000init();
763         m68k_set_cpu_type(M68K_CPU_TYPE_68000);
764         gpu_init();
765         dsp_init();
766         tom_init();
767         jerry_init();
768         cdrom_init();
769 }
770
771 unsigned jaguar_byte_read(unsigned int offset)
772 {
773         uint8 data = 0x00;
774
775         offset &= 0xFFFFFF;
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);
792         else
793                 data = jaguar_unknown_readbyte(offset);
794
795         return data;
796 }
797
798 unsigned jaguar_word_read(unsigned int offset)
799 {
800         offset &= 0xFFFFFF;
801         if (offset <= 0x3FFFFE)
802         {
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];
805         }
806         else if ((offset >= 0x800000) && (offset <= 0xBFFFFE))
807         {
808                 offset -= 0x800000;
809 //              return (jaguar_mainRom[offset+1] << 8) | jaguar_mainRom[offset+0];
810                 return (jaguar_mainRom[offset+0] << 8) | jaguar_mainRom[offset+1];
811         }
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);
822
823         return jaguar_unknown_readword(offset);
824 }
825
826 void jaguar_byte_write(unsigned offset, unsigned data)
827 {
828         offset &= 0xFFFFFF;
829         if (offset < 0x400000)
830         {
831 //              jaguar_mainRam[(offset^0x01) & 0x3FFFFF] = data;
832                 jaguar_mainRam[offset & 0x3FFFFF] = data;
833                 return;
834         }
835 //      else if ((offset >= 0xDFFF00) && (offset < 0xDFFF00))
836         else if ((offset >= 0xDFFF00) && (offset <= 0xDFFFFF))
837         {
838                 cdrom_byte_write(offset, data);
839                 return;
840         }
841         else if ((offset >= 0xF00000) && (offset <= 0xF0FFFF))
842         {
843                 tom_byte_write(offset, data);
844                 return;
845         }
846         else if ((offset >= 0xF10000) && (offset <= 0xF1FFFF))
847         {
848                 jerry_byte_write(offset, data);
849                 return;
850         }
851     
852         jaguar_unknown_writebyte(offset, data);
853 }
854
855 void jaguar_word_write(unsigned offset, unsigned data)
856 {
857         offset &= 0xFFFFFF;
858         
859         if (offset <= 0x3FFFFE)
860         {
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;
865                 return;
866         }
867         else if ((offset >= 0xDFFF00) && (offset <= 0xDFFFFE))
868         {
869                 cdrom_word_write(offset, data);
870                 return;
871         }
872         else if ((offset >= 0xF00000) && (offset <= 0xF0FFFE))
873         {
874                 tom_word_write(offset, data);
875                 return;
876         }
877         else if ((offset >= 0xF10000) && (offset <= 0xF1FFFE))
878         {
879                 jerry_word_write(offset, data);
880                 return;
881         }
882     
883         jaguar_unknown_writeword(offset, data);
884 }
885
886 unsigned jaguar_long_read(unsigned int offset)
887 {
888 /*      uint32 data = jaguar_word_read(offset);
889         data = (data<<16) | jaguar_word_read(offset+2);
890         return data;*/
891         return (jaguar_word_read(offset) << 16) | jaguar_word_read(offset+2);
892 }
893
894 void jaguar_long_write(unsigned offset, unsigned data)
895 {
896         jaguar_word_write(offset, data >> 16);
897         jaguar_word_write(offset+2, data & 0xFFFF);
898 }
899
900 void jaguar_done(void)
901 {
902         fprintf(log_get(), "jaguar_done() ...START\n");
903 #ifdef CPU_DEBUG
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();
908 #endif
909 #ifdef SOUND_OUTPUT
910         ws_audio_done();
911 #endif
912         cd_bios_done();
913         cdrom_done();
914         tom_done();
915         jerry_done();
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");
921 }
922
923 void jaguar_reset(void)
924 {
925 //      fprintf(log_get(),"jaguar_reset():\n");
926 #ifdef SOUND_OUTPUT
927         ws_audio_reset();
928 #endif
929         cd_bios_reset();
930         tom_reset();
931         jerry_reset();
932         gpu_reset();
933         dsp_reset();
934         cdrom_reset();
935 //      s68000reset();
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));
938 }
939
940 void jaguar_reset_handler(void)
941 {
942 }
943
944 void jaguar_exec(int16 * backbuffer, uint8 render)
945
946         uint32 i, vblank_duration = tom_get_vdb();
947
948         // vblank
949         if ((tom_irq_enabled(IRQ_VBLANK)) && (jaguar_interrupt_handler_is_valid(64)))
950         {
951                 if (jaguar_word_read(0xF0004E) != 0xFFFF)
952                 {
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.
959                 }
960         }
961
962         for(i=0; i<vblank_duration; i++)
963         {
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...
969
970                 cd_bios_exec(i);
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);
976                 if (dsp_enabled)
977                         dsp_exec(dsp_cycles_per_scanline);
978         }
979         
980         for (; i<jaguar_screen_scanlines; i++)
981         {
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...
987                 cd_bios_exec(i);
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);
993                 if (dsp_enabled)
994                         dsp_exec(dsp_cycles_per_scanline);
995                 backbuffer += tom_width;
996         }
997 #ifdef SOUND_OUTPUT
998         system_sound_update();
999 #endif
1000 }
1001
1002 // Temp debugging stuff
1003
1004 void DumpMainMemory(void)
1005 {
1006         FILE * fp = fopen("./memdump.bin", "wb");
1007
1008         if (fp == NULL)
1009                 return;
1010
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);
1015
1016         fclose(fp);
1017 }
1018
1019 uint8 * GetRamPtr(void)
1020 {
1021         return jaguar_mainRam;
1022 }