]> Shamusworld >> Repos - virtualjaguar/blob - src/jaguar.cpp
Initial revision
[virtualjaguar] / src / jaguar.cpp
1 //
2 // JAGUAR.CPP
3 //
4 // by cal16
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 //////////////////////////////////////////////////////////////////////////////
45 // Bios path
46 //////////////////////////////////////////////////////////////////////////////
47 //
48 //
49 //
50 //////////////////////////////////////////////////////////////////////////////
51 //static char  *jaguar_bootRom_path="c:/jaguarEmu/newload.img";
52 static char * jaguar_bootRom_path = "./bios/jagboot.rom";
53 //static char  *jaguar_bootRom_path="./bios/JagOS.bin";
54 char * jaguar_eeproms_path = "./eeproms/";
55
56 //////////////////////////////////////////////////////////////////////////////
57 //
58 //////////////////////////////////////////////////////////////////////////////
59 //
60 //
61 //
62 //////////////////////////////////////////////////////////////////////////////
63 uint32 jaguar_mainRom_crc32;
64
65 static uint32 m68k_cycles_per_scanline;
66 static uint32 gpu_cycles_per_scanline;
67 static uint32 dsp_cycles_per_scanline;
68 static uint32 jaguar_screen_scanlines;
69
70 static uint8 * jaguar_mainRam = NULL;
71 static uint8 * jaguar_bootRom = NULL;
72 static uint8 * jaguar_mainRom = NULL;
73 //////////////////////////////////////////////////////////////////////////////
74
75
76 //
77 // Musashi 68000 read/write/IRQ functions
78 //
79
80 int irq_ack_handler(int level)
81 {
82         int vector = M68K_INT_ACK_AUTOVECTOR;
83
84         if (level = 7)
85         {
86                 m68k_set_irq(0);                                                // Clear the IRQ...
87                 vector = 64;                                                    // Set user interrupt #0
88         }
89
90         return vector;
91 }
92
93 //Do this in makefile???
94 //#define LOG_UNMAPPED_MEMORY_ACCESSES 1
95
96 unsigned int m68k_read_memory_8(unsigned int address)
97 {
98 //fprintf(log_get(), "[RM8] Addr: %08X\n", address);
99         unsigned int retVal = 0;
100
101         if ((address >= 0x000000) && (address <= 0x3FFFFF))
102                 retVal = jaguar_mainRam[address];
103         else if ((address >= 0x800000) && (address <= 0xDFFFFF))
104                 retVal = jaguar_mainRom[address - 0x800000];
105         else if ((address >= 0xE00000) && (address <= 0xE3FFFF))
106                 retVal = jaguar_bootRom[address - 0xE00000];
107         else if ((address >= 0xDFFF00) && (address <= 0xDFFFFF))
108                 retVal = cdrom_byte_read(address);
109         else if ((address >= 0xF00000) && (address <= 0xF0FFFF))
110                 retVal = tom_byte_read(address);
111         else if ((address >= 0xF10000) && (address <= 0xF1FFFF))
112                 retVal = jerry_byte_read(address);
113         else
114                 retVal = jaguar_unknown_readbyte(address);
115
116     return retVal;
117 }
118
119 unsigned int m68k_read_memory_16(unsigned int address)
120 {
121 //fprintf(log_get(), "[RM16] Addr: %08X\n", address);
122     unsigned int retVal = 0;
123
124         if ((address >= 0x000000) && (address <= 0x3FFFFE))
125                 retVal = (jaguar_mainRam[address] << 8) | jaguar_mainRam[address+1];
126         else if ((address >= 0x800000) && (address <= 0xDFFFFE))
127                 retVal = (jaguar_mainRom[address - 0x800000] << 8) | jaguar_mainRom[address - 0x800000 + 1];
128         else if ((address >= 0xE00000) && (address <= 0xE3FFFE))
129                 retVal = (jaguar_bootRom[address - 0xE00000] << 8) | jaguar_bootRom[address - 0xE00000 + 1];
130         else if ((address >= 0xDFFF00) && (address <= 0xDFFFFE))
131                 retVal = cdrom_word_read(address);
132         else if ((address >= 0xF00000) && (address <= 0xF0FFFE))
133                 retVal = tom_word_read(address);
134         else if ((address >= 0xF10000) && (address <= 0xF1FFFE))
135                 retVal = jerry_word_read(address);
136         else
137 //{
138 //fprintf(log_get(), "[RM16] Unknown address: %08X\n", address);
139                 retVal = jaguar_unknown_readword(address);
140 //}
141
142     return retVal;
143 }
144
145 unsigned int m68k_read_memory_32(unsigned int address)
146 {
147 //fprintf(log_get(), "--> [RM32]\n");
148     return (m68k_read_memory_16(address) << 16) | m68k_read_memory_16(address + 2);
149 }
150
151 void m68k_write_memory_8(unsigned int address, unsigned int value)
152 {
153 //fprintf(log_get(), "[WM8  PC=%08X] Addr: %08X, val: %02X\n", m68k_get_reg(NULL, M68K_REG_PC), address, value);
154         if ((address >= 0x000000) && (address <= 0x3FFFFF))
155                 jaguar_mainRam[address] = value;
156         else if ((address >= 0xDFFF00) && (address <= 0xDFFFFF))
157                 cdrom_byte_write(address, value);
158         else if ((address >= 0xF00000) && (address <= 0xF0FFFF))
159                 tom_byte_write(address, value);
160         else if ((address >= 0xF10000) && (address <= 0xF1FFFF))
161                 jerry_byte_write(address, value);
162         else
163                 jaguar_unknown_writebyte(address, value);
164 }
165
166 void m68k_write_memory_16(unsigned int address, unsigned int value)
167 {
168 //fprintf(log_get(), "[WM16 PC=%08X] Addr: %08X, val: %04X\n", m68k_get_reg(NULL, M68K_REG_PC), address, value);
169         if ((address >= 0x000000) && (address <= 0x3FFFFE))
170         {
171                 jaguar_mainRam[address] = value >> 8;
172                 jaguar_mainRam[address + 1] = value & 0xFF;
173         }
174         else if ((address >= 0xDFFF00) && (address <= 0xDFFFFE))
175                 cdrom_word_write(address, value);
176         else if ((address >= 0xF00000) && (address <= 0xF0FFFE))
177                 tom_word_write(address, value);
178         else if ((address >= 0xF10000) && (address <= 0xF1FFFE))
179                 jerry_word_write(address, value);
180         else
181                 jaguar_unknown_writeword(address, value);
182 }
183
184 void m68k_write_memory_32(unsigned int address, unsigned int value)
185 {
186 //fprintf(log_get(), "--> [WM32]\n");
187         m68k_write_memory_16(address, value >> 16);
188         m68k_write_memory_16(address + 2, value & 0xFFFF);
189 }
190
191 //////////////////////////////////////////////////////////////////////////////
192 //
193 //
194 //
195 //////////////////////////////////////////////////////////////////////////////
196 /*struct STARSCREAM_PROGRAMREGION *jaguar_programfetch;
197 struct STARSCREAM_DATAREGION    *jaguar_readbyte;
198 struct STARSCREAM_DATAREGION    *jaguar_readword;
199 struct STARSCREAM_DATAREGION    *jaguar_writebyte;
200 struct STARSCREAM_DATAREGION    *jaguar_writeword;
201 UINT16 jaguar_regionsCount[6];*/
202
203 //////////////////////////////////////////////////////////////////////////////
204 //
205 //////////////////////////////////////////////////////////////////////////////
206 //
207 //
208 //
209 //////////////////////////////////////////////////////////////////////////////
210 uint32 jaguar_get_handler(uint32 i)
211 {
212 //      return (jaguar_word_read(i<<2) << 16) | jaguar_word_read((i<<2) + 2);
213         return (jaguar_word_read(i*4) << 16) | jaguar_word_read((i*4) + 2);
214 }
215
216 //////////////////////////////////////////////////////////////////////////////
217 //
218 //////////////////////////////////////////////////////////////////////////////
219 //
220 //
221 //
222 //
223 //
224 //////////////////////////////////////////////////////////////////////////////
225 static char romLoadDialog_filePath[1024];
226 #ifndef __PORT__
227 static char romLoadDialog_initialDirectory[1024];
228
229 int jaguar_open_rom(HWND hWnd,char *title,char *filterString)
230 {
231         OPENFILENAME ofn;
232
233
234         romLoadDialog_initialDirectory[0] = 0;
235
236
237         romLoadDialog_filePath[0] = 0;
238
239         ZeroMemory(&ofn, sizeof(OPENFILENAME));
240         ofn.lStructSize = sizeof(OPENFILENAME);
241         ofn.hwndOwner = hWnd;
242         ofn.lpstrFile = romLoadDialog_filePath;
243         ofn.nMaxFile = sizeof(romLoadDialog_filePath);
244         ofn.lpstrFilter =  filterString;
245         ofn.nFilterIndex = 0;
246         ofn.lpstrFileTitle = NULL;
247         ofn.nMaxFileTitle = 0;
248         ofn.lpstrInitialDir = (const char *)romLoadDialog_initialDirectory;
249         ofn.lpstrTitle = title; 
250         ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
251
252         if(GetOpenFileName(&ofn) == FALSE) 
253         {
254                 DWORD res = CommDlgExtendedError();
255                 SendMessage(hWnd, WM_MOVE, 0,0);
256                 return 0;
257         }
258
259
260         SendMessage(hWnd, WM_MOVE, 0,0);
261         return 1;
262 }
263 #endif
264 //////////////////////////////////////////////////////////////////////////////
265 //
266 //////////////////////////////////////////////////////////////////////////////
267 //
268 //
269 //
270 //////////////////////////////////////////////////////////////////////////////
271 uint32 jaguar_interrupt_handler_is_valid(uint32 i)
272 {
273         uint32 handler = jaguar_get_handler(i);
274         if (handler && (handler != 0xFFFFFFFF))
275                 return 1;
276         else
277                 return 0;
278 }
279 //////////////////////////////////////////////////////////////////////////////
280 //
281 //////////////////////////////////////////////////////////////////////////////
282 //
283 //
284 //
285 //////////////////////////////////////////////////////////////////////////////
286 void s68000show_context(void)
287 {
288 //      fprintf(log_get(),"\t68k PC=0x%.6x\n",s68000readPC());
289         fprintf(log_get(),"\t68k PC=0x%.6x\n", m68k_get_reg(NULL, M68K_REG_PC));
290 //      for (int i=0;i<8;i++)
291 //              fprintf(log_get(),"\tD%i = 0x%.8x\n",i,s68000context.dreg[i]);
292         for(int i=M68K_REG_D0; i<=M68K_REG_D7; i++)
293                 fprintf(log_get(), "\tD%i = 0x%.8x\n", i-M68K_REG_D0, m68k_get_reg(NULL, (m68k_register_t)i));
294         fprintf(log_get(), "\n");
295 //      for (i=0;i<8;i++)
296 //              fprintf(log_get(),"\tA%i = 0x%.8x\n",i,s68000context.areg[i]);
297         for(int i=M68K_REG_A0; i<=M68K_REG_A7; i++)
298                 fprintf(log_get(), "\tA%i = 0x%.8x\n", i-M68K_REG_A0, m68k_get_reg(NULL, (m68k_register_t)i));
299
300         fprintf(log_get(), "68k dasm\n");
301 //      jaguar_dasm(s68000readPC()-0x1000,0x20000);
302 //      jaguar_dasm(m68k_get_reg(NULL, M68K_REG_PC) - 0x1000, 0x20000);
303         jaguar_dasm(m68k_get_reg(NULL, M68K_REG_PC) - 0x80, 0x200);
304         fprintf(log_get(), "..................\n");
305
306
307         if (tom_irq_enabled(IRQ_VBLANK))
308         {
309                 fprintf(log_get(), "vblank int: enabled\n");
310                 jaguar_dasm(jaguar_get_handler(64), 0x200);
311         }
312         else
313                 fprintf(log_get(), "vblank int: disabled\n");
314         fprintf(log_get(), "..................\n");
315
316         for(int i=0; i<256; i++)
317                 fprintf(log_get(), "handler %03i at $%08X\n", i, jaguar_get_handler(i));
318 }
319
320 // Starscream crap ripped out...
321
322 //
323 // Unknown read/write byte/word routines
324 //
325
326 void jaguar_unknown_writebyte(unsigned address, unsigned data)
327 {
328 #ifdef LOG_UNMAPPED_MEMORY_ACCESSES
329         fprintf(log_get(), "jaguar: unknown byte %02X write at %08X (PC=%06X)\n", data, address, m68k_get_reg(NULL, M68K_REG_PC));
330 #endif
331 }
332
333 void jaguar_unknown_writeword(unsigned address, unsigned data)
334 {
335 #ifdef LOG_UNMAPPED_MEMORY_ACCESSES
336         fprintf(log_get(), "jaguar: unknown word %04X write at %08X (PC=%06X)\n", data, address, m68k_get_reg(NULL, M68K_REG_PC));
337 #endif
338 }
339
340 unsigned jaguar_unknown_readbyte(unsigned address)
341 {
342 #ifdef LOG_UNMAPPED_MEMORY_ACCESSES
343         fprintf(log_get(), "jaguar: unknown byte read at %08X (PC=%06X)\n", address, m68k_get_reg(NULL, M68K_REG_PC));
344 #endif
345     return 0xFF;
346 }
347
348 unsigned jaguar_unknown_readword(unsigned address)
349 {
350 #ifdef LOG_UNMAPPED_MEMORY_ACCESSES
351         fprintf(log_get(), "jaguar: unknown word read at %08X (PC=%06X)\n", address, m68k_get_reg(NULL, M68K_REG_PC));
352 #endif
353     return 0xFFFF;
354 }
355
356 //
357 // Jaguar ROM loading
358 //
359
360 uint8 * jaguar_rom_load(char * path, uint32 * romSize)
361 {
362         uint8 * rom = NULL;
363         fpos_t pos;
364         int     x;
365         __int64 filepos;
366
367         fprintf(log_get(), "jaguar: loading %s...", path);
368         FILE * fp = fopen(path, "rb");
369         if (fp == NULL)
370         {
371                 fprintf(log_get(), "failed\n");
372                 log_done();
373                 exit(0);
374                 return NULL;
375         }
376         fseek(fp, 0, SEEK_END);
377
378         /* Added by SDLEMU (http://sdlemu.ngemu.com) */
379         /* Added for GCC UNIX compatibility          */
380         #ifdef __GCCUNIX__
381         fgetpos(fp, (fpos_t *)&filepos);
382         #else
383         fgetpos(fp, &filepos);
384         #endif
385         
386         *romSize = (int)filepos;
387         fseek(fp, 0, SEEK_SET);
388         rom = (uint8 *)malloc(*romSize);
389         fread(rom, 1, *romSize, fp);
390         fclose(fp);
391         fprintf(log_get(), "ok (%i bytes)\n", *romSize);
392 //      jaguar_mainRom_crc32=crc32_calcCheckSum(jaguar_mainRom,*romSize);
393 //      fprintf(log_get(),"crc: 0x%.8x\n",jaguar_mainRom_crc32);
394         return rom;
395 }
396
397 //
398 // Load a ROM at a specific address
399 //
400
401 void jaguar_rom_load_to(uint8 * rom, char * path, uint32 * romSize)
402 {
403         __int64 filepos;
404
405         fprintf(log_get(), "jaguar: loading %s...", path);
406         FILE * fp = fopen(path, "rb");
407         if (fp == NULL)
408         {
409                 fprintf(log_get(), "failed\n");
410                 log_done();
411                 exit(0);
412                 return;
413         }
414         fseek(fp, 0, SEEK_END);
415
416         /* Added by SDLEMU (http://sdlemu.ngemu.com) */
417         /* Added for GCC UNIX compatibility          */
418         #ifdef __GCCUNIX__
419         fgetpos(fp, (fpos_t *)&filepos);
420         #else
421         fgetpos(fp, &filepos);
422         #endif
423
424         *romSize = (int)filepos;
425         fseek(fp, 0, SEEK_SET);
426         fread(rom, 1, *romSize, fp);
427         fclose(fp);
428         fprintf(log_get(), "ok (%i bytes)\n", *romSize);
429 }
430
431 //
432 // Byte swap a region of memory
433 //
434
435 void jaguar_byte_swap(uint8 * rom, uint32 size)
436 {
437         while (size > 0)
438         {
439                 uint8 tmp = rom[0];
440                 rom[0] = rom[1];
441                 rom[1] = tmp;
442                 rom += 2;
443                 size -= 2;
444         }
445 }
446
447 //
448 // Disassemble instructions at the given offset
449 //
450
451 void jaguar_dasm(uint32 offset, uint32 qt)
452 {
453         static char buffer[2048], mem[64];
454         int pc = offset, oldpc;
455
456         for(int i=0; i<qt; i++)
457         {
458                 oldpc = pc;
459                 for(int j=0; j<64; j++)
460 //                      mem[j^0x01] = jaguar_byte_read(pc + j);
461                         mem[j^0x01] = jaguar_byte_read(pc + j);
462
463                 pc += Dasm68000((char *)mem, buffer, 0);
464 #ifdef CPU_DEBUG
465                 fprintf(log_get(), "%08X: %s\n", oldpc, buffer);
466 #endif
467         }
468 }
469
470 //
471 // Jaguar cartridge ROM loading
472 //
473
474 void jaguar_load_cart(char * path, uint8 * mem, uint32 offs, uint32 boot, uint32 header)
475 {
476         uint32 romsize;
477
478         jaguar_rom_load_to(mem+offs-header, path, &romsize);
479 // Is there a need for this? The answer is !!! NO !!!
480 //      jaguar_byte_swap(mem+offs, romsize);
481         jaguar_mainRom_crc32 = crc32_calcCheckSum(jaguar_mainRom, romsize);
482         fprintf(log_get(), "crc: %08X\n", jaguar_mainRom_crc32);
483
484 // Brain dead endian dependent crap
485 //      *((uint32 *)&jaguar_mainRam[4]) = boot;
486 // This is how it *should* have been done...
487         SET32(jaguar_mainRam, 4, boot);
488 // Same as above...
489 //      jaguar_dasm((boot>>16) | (boot<<16), 32*4);
490         jaguar_dasm(boot, 32*4);
491 }
492
493 //
494 // Jaguar initialization
495 //
496
497 #ifdef __PORT__
498 void jaguar_init(const char * filename)
499 #else
500 void jaguar_init(void)
501 #endif
502 {
503         uint32 romsize;
504
505         jaguar_screen_scanlines = 525;                  // PAL screen size
506         m68k_cycles_per_scanline = 13300000 / (jaguar_screen_scanlines * 60);
507         gpu_cycles_per_scanline = (26591000 / 4) / (jaguar_screen_scanlines * 60);
508         dsp_cycles_per_scanline = (26591000 / 4) / (jaguar_screen_scanlines * 60);
509
510         memory_malloc_secure((void**)&jaguar_mainRam, 0x400000, "Jaguar 68k cpu ram");
511         memory_malloc_secure((void**)&jaguar_bootRom, 0x040000, "Jaguar 68k cpu boot rom");
512         memory_malloc_secure((void**)&jaguar_mainRom, 0x600000, "Jaguar 68k cpu rom");
513         memset(jaguar_mainRam, 0x00, 0x400000);
514
515         jaguar_rom_load_to(jaguar_bootRom, jaguar_bootRom_path, &romsize);
516 // No need to do this anymore, since Starcrap is gone!
517 //      jaguar_byte_swap(jaguar_bootRom, romsize);
518         memcpy(jaguar_mainRam, jaguar_bootRom, 8);
519 // More braindead endian dependent crap
520 //WAS:  *((uint32 *)&jaguar_mainRam[0]) = 0x00000020;
521         SET32(jaguar_mainRam, 0, 0x00200000);
522
523 #ifdef JAGUAR_WIP_RELEASE
524 #ifdef __PORT__
525         strcpy(romLoadDialog_filePath, filename);
526 #else
527         jaguar_open_rom(GetForegroundWindow(), "Load", "Jaguar roms (*.JAG)\0*.JAG\0\0");
528 #endif
529 //WAS:  jaguar_load_cart(romLoadDialog_filePath, jaguar_mainRom, 0x0000, 0x20000080, 0);
530         jaguar_load_cart(romLoadDialog_filePath, jaguar_mainRom, 0x0000, 0x00802000, 0);
531         if ((jaguar_mainRom_crc32 == 0x3966698f) || (jaguar_mainRom_crc32 == 0x5e705756)
532                 || (jaguar_mainRom_crc32 == 0x2630cbc4) || (jaguar_mainRom_crc32 == 0xd46437e8)
533                 || (jaguar_mainRom_crc32 == 0x2630cbc4))
534                 dsp_enabled = 1;
535
536         if ((jaguar_mainRom_crc32 == 0x6e90989f) || (jaguar_mainRom_crc32 == 0xfc8f0dcd)
537                 || (jaguar_mainRom_crc32 == 0x2a512a83) || (jaguar_mainRom_crc32 == 0x41307601)
538                 || (jaguar_mainRom_crc32 == 0x3c7bfda8) || (jaguar_mainRom_crc32 == 0x5e705756))
539                 gpu_cycles_per_scanline = (26591000 / 1) / (jaguar_screen_scanlines * 60);
540
541         if (jaguar_mainRom_crc32 == 0x7ae20823)
542         {
543                 dsp_enabled = 1;
544                 gpu_cycles_per_scanline = (26591000 / 1) / (jaguar_screen_scanlines * 60);
545                 dsp_cycles_per_scanline = (26591000 / 1) / (jaguar_screen_scanlines * 60);
546         }
547         if (jaguar_mainRom_crc32 == 0xe21d0e2f)
548         {
549                 dsp_enabled = 1;
550                 gpu_cycles_per_scanline = (26591000 / 1) / (jaguar_screen_scanlines * 60);
551                 dsp_cycles_per_scanline = (26591000 / 1) / (jaguar_screen_scanlines * 60);
552         }
553         if (jaguar_mainRom_crc32 == 0x66f8914c)
554         {
555                 gpu_cycles_per_scanline = (26591000 / 1) /(jaguar_screen_scanlines * 60);
556         }
557         if (jaguar_mainRom_crc32 == 0x5a5b9c68)
558         {
559                 gpu_cycles_per_scanline = (26591000 / 1) / (jaguar_screen_scanlines * 60);
560         }
561         if (jaguar_mainRom_crc32 == 0xdcb0197a)
562         {
563                 dsp_enabled = 0; // dsp not needed
564                 gpu_cycles_per_scanline = (26591000 / 1) / (jaguar_screen_scanlines * 60);
565                 //dsp_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60);
566         }
567         if ((jaguar_mainRom_crc32 == 0x3966698f) || (jaguar_mainRom_crc32 == 0xe21d0e2f))
568                 dsp_enabled = 1;
569         if (jaguar_mainRom_crc32 == 0x5e705756)
570         {
571                 gpu_cycles_per_scanline = (26591000 / 1) / (jaguar_screen_scanlines * 60);
572                 dsp_enabled = 1;
573         }
574         if (jaguar_mainRom_crc32 == 0x2630cbc4)
575         {
576                 // ultra vortek
577                 gpu_cycles_per_scanline = (26591000 / 1) / (jaguar_screen_scanlines * 60);
578                 dsp_cycles_per_scanline = (26591000 / 1) / (jaguar_screen_scanlines * 60);
579                 dsp_enabled = 1;
580         }
581         if ((jaguar_mainRom_crc32 == 0xd46437e8) || (jaguar_mainRom_crc32 == 0xba74c3ed))
582         {
583                 gpu_cycles_per_scanline = (26591000 / 1) / (jaguar_screen_scanlines * 60);
584                 dsp_enabled = 1;
585         }
586         if (jaguar_mainRom_crc32 == 0x6e90989f)
587                 gpu_cycles_per_scanline = (26591000 / 1) / (jaguar_screen_scanlines * 60);
588
589         if (jaguar_mainRom_crc32 == 0x41307601)
590         {
591                 gpu_cycles_per_scanline = (26591000 / 1) / (jaguar_screen_scanlines * 60);
592         }
593
594         if (jaguar_mainRom_crc32 == 0x8483392b)
595         {
596                 dsp_enabled = 1;
597         }
598
599 #else   // #ifdef JAGUAR_WIP_RELEASE
600 //      jaguar_load_cart("C:/ftp/jaguar/roms/roms/flashback.jag",jaguar_mainRom,0x0000, 0x20000080,0);
601 //      jaguar_load_cart("C:/ftp/jaguar/roms/roms/Pinball Fantasies.JAG",jaguar_mainRom,0x0000, 0x20000080,0);
602 //      jaguar_load_cart("C:/ftp/jaguar/roms/roms/alien vs predator (1994).jag",jaguar_mainRom,0x0000, 0x20000080,0);
603 //      jaguar_load_cart("C:/ftp/jaguar/roms/roms/cannon fodder (1995) (computer west).jag",jaguar_mainRom,0x0000, 0x20000080,0);
604 //      jaguar_load_cart("C:/ftp/jaguar/roms/roms/double dragon v (1995) (williams).jag",jaguar_mainRom,0x0000, 0x20000080,0);
605 //      jaguar_load_cart("C:/ftp/jaguar/roms/roms/Dragon - The Bruce Lee Story.JAG",jaguar_mainRom,0x0000, 0x20000080,0);
606 //      jaguar_load_cart("C:/ftp/jaguar/roms/roms/Syndicate.JAG",jaguar_mainRom,0x0000, 0x20000080,0);
607 //      jaguar_load_cart("C:/ftp/jaguar/roms/roms/Theme Park.JAG",jaguar_mainRom,0x0000, 0x20000080,0);
608 //      jaguar_load_cart("C:/ftp/jaguar/roms/roms/Brutal Sports Football.JAG",jaguar_mainRom,0x0000, 0x20000080,0);
609 //      jaguar_load_cart("C:/ftp/jaguar/roms/roms/International Sensible Soccer.JAG",jaguar_mainRom,0x0000, 0x20000080,0);
610 //  jaguar_load_cart("C:/ftp/jaguar/roms/roms/Defender 2000.JAG",jaguar_mainRom,0x0000, 0x20000080,0);
611 //      jaguar_load_cart("C:/ftp/jaguar/roms/roms/Fever Pitch Soccer.JAG",jaguar_mainRom,0x0000, 0x20000080,0);
612 //      jaguar_load_cart("C:/ftp/jaguar/roms/roms/Rayman.JAG",jaguar_mainRom,0x0000, 0x20000080,0);
613 //      jaguar_load_cart("C:/ftp/jaguar/roms/roms/Tempest 2000.JAG",jaguar_mainRom,0x0000, 0x20000080,0);
614 //      jaguar_load_cart("C:/ftp/jaguar/roms/roms/zool 2 (1994).jag",jaguar_mainRom,0x0000, 0x20000080,0);
615 //      jaguar_load_cart("C:/ftp/jaguar/roms/roms/Bubsy - Fractured Furry Tails.JAG",jaguar_mainRom,0x0000, 0x20000080,0);
616 //      jaguar_load_cart("C:/ftp/jaguar/roms/roms/Raiden.JAG",jaguar_mainRom,0x0000, 0x20000080,0);
617 //      jaguar_load_cart("C:/ftp/jaguar/roms/roms/Dino Olympics.jag",jaguar_mainRom,0x0000, 0x20000080,0);
618 //      jaguar_load_cart("C:/ftp/jaguar/roms/roms/I-War.jag",jaguar_mainRom,0x0000, 0x20000080,0);
619 //      jaguar_load_cart("C:/ftp/jaguar/roms/roms/Attack of the Mutant Penguins.JAG",jaguar_mainRom,0x0000, 0x20000080,0);
620 //      jaguar_load_cart("C:/ftp/jaguar/roms/roms/Cybermorph.jag",jaguar_mainRom,0x0000, 0x20000080,0);
621 //      jaguar_load_cart("C:/ftp/jaguar/roms/roms/Troy Aikman NFL Football (1995) (Williams).jag",jaguar_mainRom,0x0000, 0x20000080,0);
622 //      jaguar_load_cart("C:/ftp/jaguar/roms/roms/Power Drive Rally (1995) (TWI).jag",jaguar_mainRom,0x0000, 0x20000080,0);
623 //      jaguar_load_cart("C:/ftp/jaguar/roms/roms/Zoop! (1996).jag",jaguar_mainRom,0x0000, 0x20000080,0);
624 //      jaguar_load_cart("C:/ftp/jaguar/roms/roms/Missile Command 3D.JAG",jaguar_mainRom,0x0000, 0x20000080,0);
625 //      jaguar_load_cart("C:/ftp/jaguar/roms/roms/Hover Strike.jag",jaguar_mainRom,0x0000, 0x20000080,0);
626 //      jaguar_load_cart("C:/ftp/jaguar/roms/roms/worms.bin",jaguar_mainRom,0x0000, 0x20000080,0);
627 //      jaguar_load_cart("C:/ftp/jaguar/roms/roms/Atari Kart.JAG",jaguar_mainRom,0x0000, 0x20000080,0);
628 //      jaguar_load_cart("C:/ftp/jaguar/roms/roms/native.bin",jaguar_mainRam,0x5000, 0x50000000,0x00);
629
630         if (jaguar_mainRom_crc32==0xe21d0e2f)
631         {
632                 dsp_enabled=1;
633                 gpu_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60);
634                 dsp_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60);
635         }
636         if (jaguar_mainRom_crc32==0x66f8914c)
637         {
638                 gpu_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60);
639         }
640         if (jaguar_mainRom_crc32==0x5a5b9c68)
641         {
642                 gpu_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60);
643         }
644 //      jaguar_load_cart("C:/ftp/jaguar/roms/roms/Super Cross 3D.JAG",jaguar_mainRom,0x0000, 0x20000080,0);
645         if (jaguar_mainRom_crc32==0xdcb0197a)
646         {
647                 dsp_enabled=0; // dsp not needed
648                 gpu_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60);
649                 //dsp_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60);
650         }
651 //  jaguar_load_cart("C:/ftp/jaguar/roms/roms/wolfenstein 3d (1994).jag",jaguar_mainRom,0x0000, 0x20000080,0);
652         if ((jaguar_mainRom_crc32==0x3966698f)||(jaguar_mainRom_crc32==0xe21d0e2f))
653                 dsp_enabled=1;
654 //      jaguar_load_cart("C:/ftp/jaguar/roms/roms/NBA JAM.jag",jaguar_mainRom,0x0000, 0x20000080,0);
655 //      jaguar_load_cart("C:/ftp/jaguar/roms/roms/Doom - Evil Unleashed.JAG",jaguar_mainRom,0x0000, 0x20000080,0);
656         if (jaguar_mainRom_crc32==0x5e705756)
657         {
658                 gpu_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60);
659                 dsp_enabled=1;
660         }
661 //      jaguar_load_cart("C:/ftp/jaguar/roms/roms/Ultra Vortek.JAG",jaguar_mainRom,0x0000, 0x20000080,0);
662         if (jaguar_mainRom_crc32==0x2630cbc4)
663         {
664                 // ultra vortek
665                 gpu_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60);
666                 dsp_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60);
667                 dsp_enabled=1; 
668         }
669 //      jaguar_load_cart("C:/ftp/jaguar/roms/roms/fflbeta.rom",jaguar_mainRom,0x0000, 0x20000080,0);
670 //      jaguar_load_cart("C:/ftp/jaguar/roms/roms/Fight for Your Life.jag",jaguar_mainRom,0x0000, 0x20000080,0);
671         if ((jaguar_mainRom_crc32==0xd46437e8)||(jaguar_mainRom_crc32==0xba74c3ed))
672         {
673                 gpu_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60);
674 //              dsp_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60);
675                 dsp_enabled=1;
676         }
677 //      jaguar_load_cart("C:/ftp/jaguar/roms/roms/Pitfall - The Mayan Adventure.JAG",jaguar_mainRom,0x0000, 0x20000080,0);
678         if (jaguar_mainRom_crc32==0x6e90989f)
679                 gpu_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60);
680
681 // missing some sprites
682 //      jaguar_load_cart("C:/ftp/jaguar/roms/roms/Crescent Galaxy.jag",jaguar_mainRom,0x0000, 0x20000080,0);
683         if (jaguar_mainRom_crc32==0x41307601)
684         {
685                 gpu_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60);
686         }
687
688 // missing vertical bar shades  
689 //      jaguar_load_cart("C:/ftp/jaguar/roms/roms/Phase Zero (2000) (PD).rom",jaguar_mainRom,0x0000, 0x20000080,0);
690         if (jaguar_mainRom_crc32==0x8483392b)
691         {
692                 dsp_enabled=1;
693         }
694 // cpu/dsp/gpu synchronization problems
695
696
697 // locks up during the game
698 //      jaguar_load_cart("C:/ftp/jaguar/roms/roms/Club Drive.JAG",jaguar_mainRom,0x0000, 0x20000080,0);
699
700 // no parallax floor, locks up at the start of the game 
701 // jaguar_load_cart("C:/ftp/jaguar/roms/roms/Kasumi Ninja.JAG",jaguar_mainRom,0x0000, 0x20000080,0);
702
703 // displaying the sound control dialog. no way to exit from it  
704 //      jaguar_load_cart("C:/ftp/jaguar/roms/roms/Checkered Flag.JAG",jaguar_mainRom,0x0000, 0x20000080,0);
705
706 // no 3d        
707 //  jaguar_load_cart("C:/ftp/jaguar/roms/roms/Iron Soldier.jag",jaguar_mainRom,0x0000, 0x20000080,0);
708
709 // locks up at the start of the game
710 //      jaguar_load_cart("C:/ftp/jaguar/roms/roms/Super Burnout.JAG",jaguar_mainRom,0x0000, 0x20000080,0);
711         if (jaguar_mainRom_crc32==0x20ae75f4)
712         {
713                 dsp_enabled=1;
714                 gpu_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60);
715                 dsp_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60);
716         }
717 // locks up at the start of the game    
718 //      jaguar_load_cart("C:/ftp/jaguar/roms/roms/Val D'Isere Skiing & Snowboarding (1994).jag",jaguar_mainRom,0x0000, 0x20000080,0);
719         if (jaguar_mainRom_crc32==0x4664ebd1)
720         {
721                 dsp_enabled=1;
722         }
723
724 // fonctionne avec le gpu et le dsp activés et gpu Ã  frequence nominale, et dsp Ã  1/4 de la frequence nominale
725 //      jaguar_load_cart("C:/ftp/jaguar/roms/roms/white men can't jump (1995).jag",jaguar_mainRom,0x0000, 0x20000080,0);
726         if (jaguar_mainRom_crc32==0x7ae20823)
727         {
728                 dsp_enabled=1;
729                 gpu_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60);
730         }
731 // not working at all
732 //      jaguar_load_cart("C:/ftp/jaguar/roms/roms/Flip Out.JAG",jaguar_mainRom,0x0000, 0x20000080,0);
733         if (jaguar_mainRom_crc32==0x6f57dcd2)
734         {
735                 gpu_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60);
736                 dsp_enabled=0;
737
738         }
739
740         jaguar_load_cart("C:/ftp/jaguar/roms/roms/Ruiner.JAG",jaguar_mainRom,0x0000, 0x20000080,0);
741         if (jaguar_mainRom_crc32==0x6a7c7430)
742         {
743                 dsp_enabled=1;
744         }
745
746         if (jaguar_mainRom_crc32==0x2f032271)
747         {
748                 dsp_enabled=1;
749                 dsp_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60);
750                 gpu_cycles_per_scanline=(26591000/1) /((jaguar_screen_scanlines)*60);
751         }
752 //      jaguar_load_cart("C:/ftp/jaguar/roms/roms/tetris.bin",jaguar_mainRam,0x4fe4, 0x50000000,0x00);
753 //      jaguar_load_cart("C:/ftp/jaguar/roms/roms/painter.bin",jaguar_mainRam,0xffe4, 0x00000001,0x00);
754 //      jaguar_load_cart("./roms/jagcd.rom",jaguar_mainRom,0x0000, 0x20000080,0);
755
756 //      jaguar_load_cart("cart.jag",jaguar_mainRom,0x0000, 0x20000080,0);
757
758         
759 //      cd_bios_boot("C:\\ftp\\jaguar\\cd\\Brain Dead 13.cdi");
760 //      cd_bios_boot("C:\\ftp\\jaguar\\cd\\baldies.cdi");
761 //      cd_bios_boot("C:\\ftp\\jaguar\\cd\\mystdemo.cdi");
762 //      cd_bios_boot("C:\\ftp\\jaguar\\cd\\battlemorph.cdi");
763 //      cd_bios_boot("C:\\ftp\\jaguar\\cd\\primalrage.cdi");
764 //      cd_bios_boot("C:\\ftp\\jaguar\\cd\\Dragons Lair.cdi");
765
766 //      jaguar_load_cart("C:/ftp/jaguar/roms/roms/raw.jag",jaguar_mainRam,0x4000, 0x40000000,0x00);
767 #endif  // #ifdef JAGUAR_WIP_RELEASE
768
769 #ifdef JAGUAR_REAL_SPEED
770         gpu_cycles_per_scanline = (26591000 / 1) / (jaguar_screen_scanlines * 60);
771         dsp_cycles_per_scanline = (26591000 / 1) / (jaguar_screen_scanlines * 60);
772 #endif
773 #ifdef SOUND_OUTPUT
774         ws_audio_init();
775 #endif
776         if (jaguar_use_bios)
777         {
778                 memcpy(jaguar_mainRam, jaguar_bootRom, 8);
779                 *((uint32 *)&jaguar_mainRam[0]) = 0x00000020;
780         }
781
782 //      s68000init();
783         m68k_set_cpu_type(M68K_CPU_TYPE_68000);
784         gpu_init();
785         dsp_init();
786         tom_init();
787         jerry_init();
788         cdrom_init();
789 }
790 //////////////////////////////////////////////////////////////////////////////
791 //
792 //////////////////////////////////////////////////////////////////////////////
793 //
794 //
795 //
796 //
797 //
798 //
799 //////////////////////////////////////////////////////////////////////////////
800 unsigned jaguar_byte_read(unsigned int offset)
801 {
802         uint8 data = 0x00;
803
804         offset &= 0xFFFFFF;
805         if (offset < 0x400000)
806 //              data = (jaguar_mainRam[(offset^0x01) & 0x3FFFFF]);
807                 data = (jaguar_mainRam[offset & 0x3FFFFF]);
808         else if ((offset >= 0x800000) && (offset < 0xC00000))
809 //              data = (jaguar_mainRom[(offset^0x01)-0x800000]);
810                 data = (jaguar_mainRom[offset - 0x800000]);
811         else if ((offset >= 0xDFFF00) && (offset < 0xDFFF00))
812                 data = cdrom_byte_read(offset);
813         else if ((offset >= 0xE00000) && (offset < 0xE40000))
814 //              data = (jaguar_bootRom[(offset^0x01) & 0x3FFFF]);
815                 data = (jaguar_bootRom[offset & 0x3FFFF]);
816         else if ((offset >= 0xF00000) && (offset < 0xF10000))
817                 data = (tom_byte_read(offset));
818         else if ((offset >= 0xF10000) && (offset < 0xF20000))
819                 data = (jerry_byte_read(offset));
820         else
821                 data = jaguar_unknown_readbyte(offset);
822
823         return data;
824 }
825 //////////////////////////////////////////////////////////////////////////////
826 //
827 //////////////////////////////////////////////////////////////////////////////
828 //
829 //
830 //
831 //
832 //
833 //
834 //////////////////////////////////////////////////////////////////////////////
835 unsigned jaguar_word_read(unsigned int offset)
836 {
837         offset &= 0xFFFFFF;
838         if (offset < 0x400000)
839         {
840 //              return (jaguar_mainRam[(offset+1) & 0x3FFFFF] << 8) | jaguar_mainRam[(offset+0) & 0x3FFFFF];
841                 return (jaguar_mainRam[(offset+0) & 0x3FFFFF] << 8) | jaguar_mainRam[(offset+1) & 0x3FFFFF];
842         }
843         else if ((offset >= 0x800000) && (offset < 0xC00000))
844         {
845                 offset -= 0x800000;
846 //              return (jaguar_mainRom[offset+1] << 8) | jaguar_mainRom[offset+0];
847                 return (jaguar_mainRom[offset+0] << 8) | jaguar_mainRom[offset+1];
848         }
849         else if ((offset >= 0xDFFF00) && (offset < 0xDFFF00))
850                 return cdrom_word_read(offset);
851         else if ((offset >= 0xE00000) && (offset < 0xE40000))
852                 return *((uint16 *)&jaguar_bootRom[offset & 0x3FFFF]);
853         else if ((offset >= 0xF00000) && (offset < 0xF10000))
854                 return tom_word_read(offset);
855         else if ((offset >= 0xF10000) && (offset < 0xF20000))
856                 return jerry_word_read(offset);
857
858         return jaguar_unknown_readword(offset);
859 }
860 //////////////////////////////////////////////////////////////////////////////
861 //
862 //////////////////////////////////////////////////////////////////////////////
863 //
864 //
865 //
866 //
867 //
868 //
869 //////////////////////////////////////////////////////////////////////////////
870 void jaguar_byte_write(unsigned  offset, unsigned  data)
871 {
872         offset &= 0xFFFFFF;
873         if (offset < 0x400000)
874         {
875 //              jaguar_mainRam[(offset^0x01) & 0x3FFFFF] = data;
876                 jaguar_mainRam[offset & 0x3FFFFF] = data;
877                 return;
878         }
879         else if ((offset >= 0xDFFF00) && (offset < 0xDFFF00))
880         {
881                 cdrom_byte_write(offset, data);
882                 return;
883         }
884         else if ((offset >= 0xF00000) && (offset < 0xF10000))
885         {
886                 tom_byte_write(offset, data);
887                 return;
888         }
889         else if ((offset >= 0xF10000) && (offset < 0xF20000))
890         {
891                 jerry_byte_write(offset, data);
892                 return;
893         }
894     
895         jaguar_unknown_writebyte(offset, data);
896 }
897 //////////////////////////////////////////////////////////////////////////////
898 //
899 //////////////////////////////////////////////////////////////////////////////
900 //
901 //
902 //
903 //
904 //
905 //
906 //////////////////////////////////////////////////////////////////////////////
907 void jaguar_word_write(unsigned offset, unsigned data)
908 {
909         offset &= 0xFFFFFF;
910         
911         if (offset < 0x400000)
912         {
913 //              jaguar_mainRam[(offset+0) & 0x3FFFFF] = data & 0xFF;
914 //              jaguar_mainRam[(offset+1) & 0x3FFFFF] = (data>>8) & 0xFF;
915                 jaguar_mainRam[(offset+0) & 0x3FFFFF] = (data>>8) & 0xFF;
916                 jaguar_mainRam[(offset+1) & 0x3FFFFF] = data & 0xFF;
917                 return;
918         }
919         else if ((offset >= 0xDFFF00) && (offset < 0xDFFFFF))
920         {
921                 cdrom_word_write(offset, data);
922                 return;
923         }
924         else if ((offset >= 0xF00000) && (offset < 0xF10000))
925         {
926                 tom_word_write(offset, data);
927                 return;
928         }
929         else if ((offset >= 0xF10000) && (offset < 0xF20000))
930         {
931                 jerry_word_write(offset, data);
932                 return;
933         }
934     
935         jaguar_unknown_writeword(offset, data);
936 }
937 //////////////////////////////////////////////////////////////////////////////
938 //
939 //////////////////////////////////////////////////////////////////////////////
940 //
941 //
942 //
943 //
944 //
945 //
946 //////////////////////////////////////////////////////////////////////////////
947 unsigned jaguar_long_read(unsigned int offset)
948 {
949 /*      uint32 data = jaguar_word_read(offset);
950         data = (data<<16) | jaguar_word_read(offset+2);
951         return data;*/
952         return (jaguar_word_read(offset) << 16) | jaguar_word_read(offset+2);
953 }
954 //////////////////////////////////////////////////////////////////////////////
955 //
956 //////////////////////////////////////////////////////////////////////////////
957 //
958 //
959 //
960 //
961 //
962 //
963 //////////////////////////////////////////////////////////////////////////////
964 void jaguar_long_write(unsigned offset, unsigned data)
965 {
966         jaguar_word_write(offset, data >> 16);
967         jaguar_word_write(offset+2, data & 0xFFFF);
968 }
969 //////////////////////////////////////////////////////////////////////////////
970 //
971 //////////////////////////////////////////////////////////////////////////////
972 //
973 //
974 //
975 //
976 //
977 //
978 //////////////////////////////////////////////////////////////////////////////
979 void jaguar_done(void)
980 {
981         fprintf(log_get(), "jaguar: top of stack: %08X\n", jaguar_long_read(0x001FFFF8));
982 //      fprintf(log_get(),"jaguar: cd bios version 0x%.4x\n",jaguar_word_read(0x3004));
983 //      fprintf(log_get(),"jaguar: vbl interrupt is %s\n",((tom_irq_enabled(IRQ_VBLANK))&&(jaguar_interrupt_handler_is_valid(64)))?"enabled":"disabled");
984         s68000show_context();
985 #ifdef SOUND_OUTPUT
986         ws_audio_done();
987 #endif
988         cd_bios_done();
989         cdrom_done();
990         tom_done();
991         jerry_done();
992 //      jaguar_regionsDone();
993         memory_free(jaguar_mainRom);
994         memory_free(jaguar_bootRom);
995         memory_free(jaguar_mainRam);
996 //      fprintf(log_get(),"jaguar_done()\n");
997 }
998 //////////////////////////////////////////////////////////////////////////////
999 //
1000 //////////////////////////////////////////////////////////////////////////////
1001 //
1002 //
1003 //
1004 //
1005 //
1006 //
1007 //////////////////////////////////////////////////////////////////////////////
1008 void jaguar_reset(void)
1009 {
1010 //      fprintf(log_get(),"jaguar_reset():\n");
1011 #ifdef SOUND_OUTPUT
1012         ws_audio_reset();
1013 #endif
1014         cd_bios_reset();
1015         tom_reset();
1016         jerry_reset();
1017         gpu_reset();
1018         dsp_reset();
1019         cdrom_reset();
1020 //      s68000reset();
1021     m68k_pulse_reset();                         // Reset the 68000
1022         fprintf(log_get(), "\t68K PC=%06X SP=%08X\n", m68k_get_reg(NULL, M68K_REG_PC), m68k_get_reg(NULL, M68K_REG_A7));
1023 }
1024 //////////////////////////////////////////////////////////////////////////////
1025 //
1026 //////////////////////////////////////////////////////////////////////////////
1027 //
1028 //
1029 //
1030 //////////////////////////////////////////////////////////////////////////////
1031 void jaguar_reset_handler(void)
1032 {
1033 }
1034 //////////////////////////////////////////////////////////////////////////////
1035 //
1036 //////////////////////////////////////////////////////////////////////////////
1037 //
1038 //
1039 //
1040 //////////////////////////////////////////////////////////////////////////////
1041 void jaguar_exec(int16 * backbuffer, uint8 render)
1042
1043         int i;
1044         uint32 vblank_duration = tom_get_vdb();
1045
1046         // vblank
1047         if ((tom_irq_enabled(IRQ_VBLANK)) && (jaguar_interrupt_handler_is_valid(64)))
1048         {
1049                 if (jaguar_word_read(0xF0004E) != 0xFFFF)
1050                 {
1051                         tom_set_pending_video_int();
1052 //                      s68000interrupt(7, IRQ_VBLANK+64);
1053 //                      s68000flushInterrupts();
1054                         m68k_set_irq(7);                                        // IRQ_VBLANK+64??? Not autovectored??? No.
1055 // Could set a global variable here, to signal that this is a VBLANK interrupt...
1056 // Then again, since IRQ_VBLANK is set to zero, this would not be necessary in this case.
1057                 }
1058         }
1059         for(i=0; i<vblank_duration; i++)
1060         {
1061 /*              uint32 invalid_instruction_address = s68000exec(m68k_cycles_per_scanline);
1062                 if (invalid_instruction_address != 0x80000000)
1063                         cd_bios_process(invalid_instruction_address);*/
1064                 m68k_execute(m68k_cycles_per_scanline);
1065                 // No CD handling... Hmm...
1066
1067                 cd_bios_exec(i);
1068                 tom_pit_exec(m68k_cycles_per_scanline);
1069                 tom_exec_scanline(backbuffer, i, 0);
1070                 jerry_pit_exec(m68k_cycles_per_scanline);
1071                 jerry_i2s_exec(m68k_cycles_per_scanline);
1072                 gpu_exec(gpu_cycles_per_scanline);
1073                 if (dsp_enabled)
1074                         dsp_exec(dsp_cycles_per_scanline);
1075         }
1076         
1077         for (; i<jaguar_screen_scanlines; i++)
1078         {
1079 /*              uint32 invalid_instruction_address = s68000exec(m68k_cycles_per_scanline);
1080                 if (invalid_instruction_address != 0x80000000)
1081                         cd_bios_process(invalid_instruction_address);*/
1082                 m68k_execute(m68k_cycles_per_scanline);
1083                 // No CD handling... Hmm...
1084                 cd_bios_exec(i);
1085                 tom_pit_exec(m68k_cycles_per_scanline);
1086                 jerry_pit_exec(m68k_cycles_per_scanline);
1087                 jerry_i2s_exec(m68k_cycles_per_scanline);
1088                 tom_exec_scanline(backbuffer, i, render);
1089                 gpu_exec(gpu_cycles_per_scanline);
1090                 if (dsp_enabled)
1091                         dsp_exec(dsp_cycles_per_scanline);
1092                 backbuffer += tom_width;
1093         }
1094 #ifdef SOUND_OUTPUT
1095         system_sound_update();
1096 #endif
1097 }