]> Shamusworld >> Repos - virtualjaguar/blob - src/tom.cpp
Initial revision
[virtualjaguar] / src / tom.cpp
1 //
2 // TOM Processing
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 // Note: TOM has only a 16K memory space
11 //
12 //      ------------------------------------------------------------
13 //      TOM REGISTERS (Mapped by Aaron Giles)
14 //      ------------------------------------------------------------
15 //      F00000-F0FFFF   R/W   xxxxxxxx xxxxxxxx   Internal Registers
16 //      F00000          R/W   -x-xx--- xxxxxxxx   MEMCON1 - memory config reg 1
17 //                            -x------ --------      (CPU32 - is the CPU 32bits?)
18 //                            ---xx--- --------      (IOSPEED - external I/O clock cycles)
19 //                            -------- x-------      (FASTROM - reduces ROM clock cycles)
20 //                            -------- -xx-----      (DRAMSPEED - sets RAM clock cycles)
21 //                            -------- ---xx---      (ROMSPEED - sets ROM clock cycles)
22 //                            -------- -----xx-      (ROMWIDTH - sets width of ROM: 8,16,32,64 bits)
23 //                            -------- -------x      (ROMHI - controls ROM mapping)
24 //      F00002          R/W   --xxxxxx xxxxxxxx   MEMCON2 - memory config reg 2
25 //                            --x----- --------      (HILO - image display bit order)
26 //                            ---x---- --------      (BIGEND - big endian addressing?)
27 //                            ----xxxx --------      (REFRATE - DRAM refresh rate)
28 //                            -------- xx------      (DWIDTH1 - DRAM1 width: 8,16,32,64 bits)
29 //                            -------- --xx----      (COLS1 - DRAM1 columns: 256,512,1024,2048)
30 //                            -------- ----xx--      (DWIDTH0 - DRAM0 width: 8,16,32,64 bits)
31 //                            -------- ------xx      (COLS0 - DRAM0 columns: 256,512,1024,2048)
32 //      F00004          R/W   -----xxx xxxxxxxx   HC - horizontal count
33 //                            -----x-- --------      (which half of the display)
34 //                            ------xx xxxxxxxx      (10-bit counter)
35 //      F00006          R/W   ----xxxx xxxxxxxx   VC - vertical count
36 //                            ----x--- --------      (which field is being generated)
37 //                            -----xxx xxxxxxxx      (11-bit counter)
38 //      F00008          R     -----xxx xxxxxxxx   LPH - light pen horizontal position
39 //      F0000A          R     -----xxx xxxxxxxx   LPV - light pen vertical position
40 //      F00010-F00017   R     xxxxxxxx xxxxxxxx   OB - current object code from the graphics processor
41 //      F00020-F00023     W   xxxxxxxx xxxxxxxx   OLP - start of the object list
42 //      F00026            W   -------- -------x   OBF - object processor flag
43 //      F00028            W   ----xxxx xxxxxxxx   VMODE - video mode
44 //                        W   ----xxx- --------      (PWIDTH1-8 - width of pixel in video clock cycles)
45 //                        W   -------x --------      (VARMOD - enable variable color resolution)
46 //                        W   -------- x-------      (BGEN - clear line buffere to BG color)
47 //                        W   -------- -x------      (CSYNC - enable composite sync on VSYNC)
48 //                        W   -------- --x-----      (BINC - local border color if INCEN)
49 //                        W   -------- ---x----      (INCEN - encrustation enable)
50 //                        W   -------- ----x---      (GENLOCK - enable genlock)
51 //                        W   -------- -----xx-      (MODE - CRY16,RGB24,DIRECT16,RGB16)
52 //                        W   -------- -------x      (VIDEN - enables video)
53 //      F0002A            W   xxxxxxxx xxxxxxxx   BORD1 - border color (red/green)
54 //      F0002C            W   -------- xxxxxxxx   BORD2 - border color (blue)
55 //      F0002E            W   ------xx xxxxxxxx   HP - horizontal period
56 //      F00030            W   -----xxx xxxxxxxx   HBB - horizontal blanking begin
57 //      F00032            W   -----xxx xxxxxxxx   HBE - horizontal blanking end
58 //      F00034            W   -----xxx xxxxxxxx   HSYNC - horizontal sync
59 //      F00036            W   ------xx xxxxxxxx   HVS - horizontal vertical sync
60 //      F00038            W   -----xxx xxxxxxxx   HDB1 - horizontal display begin 1
61 //      F0003A            W   -----xxx xxxxxxxx   HDB2 - horizontal display begin 2
62 //      F0003C            W   -----xxx xxxxxxxx   HDE - horizontal display end
63 //      F0003E            W   -----xxx xxxxxxxx   VP - vertical period
64 //      F00040            W   -----xxx xxxxxxxx   VBB - vertical blanking begin
65 //      F00042            W   -----xxx xxxxxxxx   VBE - vertical blanking end
66 //      F00044            W   -----xxx xxxxxxxx   VS - vertical sync
67 //      F00046            W   -----xxx xxxxxxxx   VDB - vertical display begin
68 //      F00048            W   -----xxx xxxxxxxx   VDE - vertical display end
69 //      F0004A            W   -----xxx xxxxxxxx   VEB - vertical equalization begin
70 //      F0004C            W   -----xxx xxxxxxxx   VEE - vertical equalization end
71 //      F0004E            W   -----xxx xxxxxxxx   VI - vertical interrupt
72 //      F00050            W   xxxxxxxx xxxxxxxx   PIT0 - programmable interrupt timer 0
73 //      F00052            W   xxxxxxxx xxxxxxxx   PIT1 - programmable interrupt timer 1
74 //      F00054            W   ------xx xxxxxxxx   HEQ - horizontal equalization end
75 //      F00058            W   xxxxxxxx xxxxxxxx   BG - background color
76 //      F000E0          R/W   ---xxxxx ---xxxxx   INT1 - CPU interrupt control register
77 //                            ---x---- --------      (C_JERCLR - clear pending Jerry ints)
78 //                            ----x--- --------      (C_PITCLR - clear pending PIT ints)
79 //                            -----x-- --------      (C_OPCLR - clear pending object processor ints)
80 //                            ------x- --------      (C_GPUCLR - clear pending graphics processor ints)
81 //                            -------x --------      (C_VIDCLR - clear pending video timebase ints)
82 //                            -------- ---x----      (C_JERENA - enable Jerry ints)
83 //                            -------- ----x---      (C_PITENA - enable PIT ints)
84 //                            -------- -----x--      (C_OPENA - enable object processor ints)
85 //                            -------- ------x-      (C_GPUENA - enable graphics processor ints)
86 //                            -------- -------x      (C_VIDENA - enable video timebase ints)
87 //      F000E2            W   -------- --------   INT2 - CPU interrupt resume register
88 //      F00400-F005FF   R/W   xxxxxxxx xxxxxxxx   CLUT - color lookup table A
89 //      F00600-F007FF   R/W   xxxxxxxx xxxxxxxx   CLUT - color lookup table B
90 //      F00800-F00D9F   R/W   xxxxxxxx xxxxxxxx   LBUF - line buffer A
91 //      F01000-F0159F   R/W   xxxxxxxx xxxxxxxx   LBUF - line buffer B
92 //      F01800-F01D9F   R/W   xxxxxxxx xxxxxxxx   LBUF - line buffer currently selected
93 //      ------------------------------------------------------------
94 //      F02000-F021FF   R/W   xxxxxxxx xxxxxxxx   GPU control registers
95 //      F02100          R/W   xxxxxxxx xxxxxxxx   G_FLAGS - GPU flags register
96 //                      R/W   x------- --------      (DMAEN - DMA enable)
97 //                      R/W   -x------ --------      (REGPAGE - register page)
98 //                        W   --x----- --------      (G_BLITCLR - clear blitter interrupt)
99 //                        W   ---x---- --------      (G_OPCLR - clear object processor int)
100 //                        W   ----x--- --------      (G_PITCLR - clear PIT interrupt)
101 //                        W   -----x-- --------      (G_JERCLR - clear Jerry interrupt)
102 //                        W   ------x- --------      (G_CPUCLR - clear CPU interrupt)
103 //                      R/W   -------x --------      (G_BLITENA - enable blitter interrupt)
104 //                      R/W   -------- x-------      (G_OPENA - enable object processor int)
105 //                      R/W   -------- -x------      (G_PITENA - enable PIT interrupt)
106 //                      R/W   -------- --x-----      (G_JERENA - enable Jerry interrupt)
107 //                      R/W   -------- ---x----      (G_CPUENA - enable CPU interrupt)
108 //                      R/W   -------- ----x---      (IMASK - interrupt mask)
109 //                      R/W   -------- -----x--      (NEGA_FLAG - ALU negative)
110 //                      R/W   -------- ------x-      (CARRY_FLAG - ALU carry)
111 //                      R/W   -------- -------x      (ZERO_FLAG - ALU zero)
112 //      F02104            W   -------- ----xxxx   G_MTXC - matrix control register
113 //                        W   -------- ----x---      (MATCOL - column/row major)
114 //                        W   -------- -----xxx      (MATRIX3-15 - matrix width)
115 //      F02108            W   ----xxxx xxxxxx--   G_MTXA - matrix address register
116 //      F0210C            W   -------- -----xxx   G_END - data organization register
117 //                        W   -------- -----x--      (BIG_INST - big endian instruction fetch)
118 //                        W   -------- ------x-      (BIG_PIX - big endian pixels)
119 //                        W   -------- -------x      (BIG_IO - big endian I/O)
120 //      F02110          R/W   xxxxxxxx xxxxxxxx   G_PC - GPU program counter
121 //      F02114          R/W   xxxxxxxx xx-xxxxx   G_CTRL - GPU control/status register
122 //                      R     xxxx---- --------      (VERSION - GPU version code)
123 //                      R/W   ----x--- --------      (BUS_HOG - hog the bus!)
124 //                      R/W   -----x-- --------      (G_BLITLAT - blitter interrupt latch)
125 //                      R/W   ------x- --------      (G_OPLAT - object processor int latch)
126 //                      R/W   -------x --------      (G_PITLAT - PIT interrupt latch)
127 //                      R/W   -------- x-------      (G_JERLAT - Jerry interrupt latch)
128 //                      R/W   -------- -x------      (G_CPULAT - CPU interrupt latch)
129 //                      R/W   -------- ---x----      (SINGLE_GO - single step one instruction)
130 //                      R/W   -------- ----x---      (SINGLE_STEP - single step mode)
131 //                      R/W   -------- -----x--      (FORCEINT0 - cause interrupt 0 on GPU)
132 //                      R/W   -------- ------x-      (CPUINT - send GPU interrupt to CPU)
133 //                      R/W   -------- -------x      (GPUGO - enable GPU execution)
134 //      F02118-F0211B   R/W   xxxxxxxx xxxxxxxx   G_HIDATA - high data register
135 //      F0211C-F0211F   R     xxxxxxxx xxxxxxxx   G_REMAIN - divide unit remainder
136 //      F0211C            W   -------- -------x   G_DIVCTRL - divide unit control
137 //                        W   -------- -------x      (DIV_OFFSET - 1=16.16 divide, 0=32-bit divide)
138 //      ------------------------------------------------------------
139
140 #ifndef __PORT__
141 #include <windows.h>
142 #endif
143 #include <SDL.h>
144 #include "SDLptc.h"
145 #include "tom.h"
146 #include "gpu.h"
147 #include "objectp.h"
148 #include "cry2rgb.h"
149
150
151 extern uint32 jaguar_mainRom_crc32;
152
153 //This can be defined in the makefile as well...
154 //#define TOM_DEBUG
155
156 extern Console console;
157 extern Surface * surface;
158
159 // This makes sense IFF it's being used in an endian friendly way. Currently, it's not.
160 //#define SWAP_32_ALL(A) ((SWAP_16(A>>16))|(SWAP_16(A<<16))) 
161 //#define SWAP_32(A) ((A>>16)|(A<<16))
162 //#define SWAP_16(A) ((A>>8)|(A<<8))
163 // These are more endian friendly...
164 #define SET16(addr, val)        tom_ram_8[addr] = ((val) & 0xFF00) >> 8, tom_ram_8[addr+1] = (val) & 0x00FF
165 #define GET16(addr)                     (tom_ram_8[addr] << 8) | tom_ram_8[addr+1]
166
167 static uint8 * tom_ram_8;
168 // This is just braindead and wrong!
169 //static uint16 * tom_ram_16;
170 //static uint32 * tom_ram_32;
171
172 /*
173 #define MEMCON1 tom_ram_16[0]
174 #define MEMCON2 tom_ram_16[1]
175 #define VMODE   tom_ram_16[0x28>>1]
176 #define VBB             tom_ram_16[0x40>>1]
177 #define VBE             tom_ram_16[0x42>>1]
178 #define VDB             tom_ram_16[0x46>>1]
179 #define VDE             tom_ram_16[0x48>>1]
180
181 #define BG              tom_ram_16[0x58>>1]
182
183 #define HBB             tom_ram_16[0x30>>1]
184 #define HBE             tom_ram_16[0x32>>1]
185 #define HDB             tom_ram_16[0x38>>1]
186 #define HDE             tom_ram_16[0x3C>>1]
187
188 #define HP              tom_ram_16[0x2E>>1]
189 #define VP              tom_ram_16[0x3E>>1]
190 #define VS              tom_ram_16[0x44>>1]
191
192 #define BKGCOLOR tom_ram_16[0x58>>1]
193 */
194 #define MEMCON1         0x00
195 #define MEMCON2         0x02
196 #define VMODE           0x28
197 #define HP                      0x2E
198 #define HBB                     0x30
199 #define HBE                     0x32
200 #define HDB                     0x38
201 #define HDE                     0x3C
202 #define VP                      0x3E
203 #define VBB                     0x40
204 #define VBE                     0x42
205 #define VS                      0x44
206 #define VDB                     0x46
207 #define VDE                     0x48
208 #define BG                      0x58
209
210
211 uint32 tom_width, tom_height, tom_real_internal_width;
212
213 static uint32 tom_timer_prescaler;
214 static uint32 tom_timer_divider;
215 static int32 tom_timer_counter;
216
217 uint32 tom_scanline;
218 uint32 hblankWidthInPixels = 0;
219
220 static char * videoMode_to_str[8] =
221         {"16 bpp CRY", "24 bpp RGB", "16 bpp DIRECT", "16 bpp RGB",
222         "Mixed mode", "24 bpp RGB", "16 bpp DIRECT", "16 bpp RGB"};
223
224 extern uint8 objectp_running;
225
226 typedef void (render_xxx_scanline_fn)(int16 *);
227
228 void tom_render_16bpp_cry_scanline(int16 * backbuffer);
229 void tom_render_24bpp_scanline(int16 * backbuffer);
230 void tom_render_16bpp_direct_scanline(int16 * backbuffer);
231 void tom_render_16bpp_rgb_scanline(int16 * backbuffer);
232 void tom_render_16bpp_cry_rgb_mix_scanline(int16 * backbuffer);
233
234 void tom_render_16bpp_cry_stretch_scanline(int16 * backbuffer);
235 void tom_render_24bpp_stretch_scanline(int16 * backbuffer);
236 void tom_render_16bpp_direct_stretch_scanline(int16 * backbuffer);
237 void tom_render_16bpp_rgb_stretch_scanline(int16 * backbuffer);
238 void tom_render_16bpp_cry_rgb_mix_stretch_scanline(int16 * backbuffer);
239
240 render_xxx_scanline_fn * scanline_render_normal[]=
241 {
242         tom_render_16bpp_cry_scanline,
243         tom_render_24bpp_scanline,
244         tom_render_16bpp_direct_scanline,
245         tom_render_16bpp_rgb_scanline,
246         tom_render_16bpp_cry_rgb_mix_scanline,
247         tom_render_24bpp_scanline,
248         tom_render_16bpp_direct_scanline,
249         tom_render_16bpp_rgb_scanline,
250 };
251 render_xxx_scanline_fn * scanline_render_stretch[]=
252 {
253         tom_render_16bpp_cry_stretch_scanline,
254         tom_render_24bpp_stretch_scanline,
255         tom_render_16bpp_direct_stretch_scanline,
256         tom_render_16bpp_rgb_stretch_scanline,
257         tom_render_16bpp_cry_rgb_mix_stretch_scanline,
258         tom_render_24bpp_stretch_scanline,
259         tom_render_16bpp_direct_stretch_scanline,
260         tom_render_16bpp_rgb_stretch_scanline,
261 };
262 render_xxx_scanline_fn * scanline_render[8];
263
264 uint16 tom_puck_int_pending;
265 uint16 tom_timer_int_pending;
266 uint16 tom_object_int_pending;
267 uint16 tom_gpu_int_pending;
268 uint16 tom_video_int_pending;
269
270 uint16 * tom_cry_rgb_mix_lut;
271
272 //////////////////////////////////////////////////////////////////////////////
273 //
274 //////////////////////////////////////////////////////////////////////////////
275 //
276 //
277 //
278 //
279 //
280 //
281 //////////////////////////////////////////////////////////////////////////////
282 void tom_calc_cry_rgb_mix_lut(void)
283 {
284         uint32 chrm, chrl, y;
285
286         memory_malloc_secure((void **)&tom_cry_rgb_mix_lut, 0x20000, "cry/rgb mixed mode lut");
287
288         for (uint32 i=0; i<0x10000; i++)
289         {
290                 uint16 color=i;
291
292                 if (color & 0x01)
293                 {
294                         color >>= 1;
295                         color = (color & 0x007C00) | ((color & 0x00003E0) >> 5) | ((color & 0x0000001F) << 5);
296                 }
297                 else
298                 {
299                         chrm = (color & 0xF000) >> 12;    
300                         chrl = (color & 0x0F00) >> 8;
301                         y    = (color & 0x00FF);
302                                         
303                         uint16 red   = ((((uint32)redcv[chrm][chrl]) * y) >> 11);
304                         uint16 green = ((((uint32)greencv[chrm][chrl]) * y) >> 11);
305                         uint16 blue  = ((((uint32)bluecv[chrm][chrl]) * y) >> 11);
306                         color = (red << 10) | (green << 5) | blue;
307                 }
308                 tom_cry_rgb_mix_lut[i] = color;
309         }
310 }
311
312 void tom_set_pending_puck_int(void)
313 {
314         tom_puck_int_pending = 1;
315 }
316
317 void tom_set_pending_timer_int(void)
318 {
319         tom_timer_int_pending = 1;
320 }
321
322 void tom_set_pending_object_int(void)
323 {
324         tom_object_int_pending = 1;
325 }
326
327 void tom_set_pending_gpu_int(void)
328 {
329         tom_gpu_int_pending = 1;
330 }
331
332 void tom_set_pending_video_int(void)
333 {
334         tom_video_int_pending = 1;
335 }
336
337 uint8 * tom_get_ram_pointer(void)
338 {
339         return tom_ram_8;
340 }
341 //////////////////////////////////////////////////////////////////////////////
342 //
343 //////////////////////////////////////////////////////////////////////////////
344 //
345 //
346 //
347 //
348 //
349 //
350 //////////////////////////////////////////////////////////////////////////////
351 uint8 tom_getVideoMode(void)
352 {
353 //      uint16 vmode = SWAP_16(VMODE);
354         uint16 vmode = GET16(VMODE);
355         return ((vmode >> 1) & 0x03) | ((vmode & 0x100) >> 6);
356 }
357
358 //////////////////////////////////////////////////////////////////////////////
359 //
360 //////////////////////////////////////////////////////////////////////////////
361 //
362 //
363 //
364 //
365 //
366 //
367 //////////////////////////////////////////////////////////////////////////////
368 uint16 tom_get_scanline(void)
369 {
370         return tom_scanline;
371 }
372 //////////////////////////////////////////////////////////////////////////////
373 //
374 //////////////////////////////////////////////////////////////////////////////
375 //
376 //
377 //
378 //
379 //
380 //
381 //////////////////////////////////////////////////////////////////////////////
382 uint16 tom_get_hdb(void)
383 {
384 //      return SWAP_16(HDB);
385         return GET16(HDB);
386 }
387 //////////////////////////////////////////////////////////////////////////////
388 //
389 //////////////////////////////////////////////////////////////////////////////
390 //
391 //
392 //
393 //
394 //
395 //
396 //////////////////////////////////////////////////////////////////////////////
397 uint16 tom_get_vdb(void)
398 {
399 //      return SWAP_16(VBE);
400         return GET16(VBE);
401 }
402 //////////////////////////////////////////////////////////////////////////////
403 //
404 //////////////////////////////////////////////////////////////////////////////
405 //
406 //
407 //
408 //
409 //
410 //
411 //////////////////////////////////////////////////////////////////////////////
412 void tom_render_16bpp_cry_rgb_mix_scanline(int16 * backbuffer)
413 {
414         uint32 chrm, chrl, y;
415
416         uint16 width = tom_width;
417         uint8 * current_line_buffer=(uint8 *)&tom_ram_8[0x1800];
418         
419         while (width)
420         {
421                 uint16 color;
422                 color = *current_line_buffer++;
423                 color <<= 8;
424                 color |= *current_line_buffer++;
425                 *backbuffer++ = tom_cry_rgb_mix_lut[color];
426                 width--;
427         }
428 }
429 //////////////////////////////////////////////////////////////////////////////
430 //
431 //////////////////////////////////////////////////////////////////////////////
432 //
433 //
434 //
435 //
436 //
437 //
438 //////////////////////////////////////////////////////////////////////////////
439 void tom_render_16bpp_cry_scanline(int16 *backbuffer)
440 {
441         uint32 chrm, chrl, y;
442
443         uint16 width=tom_width;
444         uint8 *current_line_buffer=(uint8*)&tom_ram_8[0x1800];
445         
446         while (width)
447         {
448                 uint16 color;
449                 color=*current_line_buffer++;
450                 color<<=8;
451                 color|=*current_line_buffer++;
452                 
453                 chrm = (color & 0xF000) >> 12;    
454                 chrl = (color & 0x0F00) >> 8;
455                 y    = (color & 0x00FF);
456                                 
457                 uint16 red   =  ((((uint32)redcv[chrm][chrl])*y)>>11);
458                 uint16 green =  ((((uint32)greencv[chrm][chrl])*y)>>11);
459                 uint16 blue  =  ((((uint32)bluecv[chrm][chrl])*y)>>11);
460                 
461                 
462                 *backbuffer++=(red<<10)|(green<<5)|blue;
463                 width--;
464         }
465 }
466 //////////////////////////////////////////////////////////////////////////////
467 //
468 //////////////////////////////////////////////////////////////////////////////
469 //
470 //
471 //
472 //
473 //
474 //
475 //////////////////////////////////////////////////////////////////////////////
476 void tom_render_24bpp_scanline(int16 *backbuffer)
477 {
478         uint16 width=tom_width;
479         uint8 *current_line_buffer=(uint8*)&tom_ram_8[0x1800];
480         
481         while (width)
482         {
483                 uint16 green=*current_line_buffer++;
484                 uint16 red=*current_line_buffer++;
485                 uint16 nc=*current_line_buffer++;
486                 uint16 blue=*current_line_buffer++;
487                 red>>=3;
488                 green>>=3;
489                 blue>>=3;
490                 *backbuffer++=(red<<10)|(green<<5)|blue;
491                 width--;
492         }
493 }
494 //////////////////////////////////////////////////////////////////////////////
495 //
496 //////////////////////////////////////////////////////////////////////////////
497 //
498 //
499 //
500 //
501 //
502 //
503 //////////////////////////////////////////////////////////////////////////////
504 void tom_render_16bpp_direct_scanline(int16 *backbuffer)
505 {
506         uint16 width=tom_width;
507         uint8 *current_line_buffer=(uint8*)&tom_ram_8[0x1800];
508         
509         while (width)
510         {
511                 uint16 color=*current_line_buffer++;
512                 color<<=8;
513                 color|=*current_line_buffer++;
514                 color>>=1;
515                 *backbuffer++=color;
516                 width--;
517         }
518 }
519 //////////////////////////////////////////////////////////////////////////////
520 //
521 //////////////////////////////////////////////////////////////////////////////
522 //
523 //
524 //
525 //
526 //
527 //
528 //////////////////////////////////////////////////////////////////////////////
529 void tom_render_16bpp_rgb_scanline(int16 *backbuffer)
530 {
531         uint16 width=tom_width;
532         uint8 *current_line_buffer=(uint8*)&tom_ram_8[0x1800];
533         
534         while (width)
535         {
536                 uint16 color=*current_line_buffer++;
537                 color<<=8;
538                 color|=*current_line_buffer++;
539                 color>>=1;
540                 color=(color&0x007c00)|((color&0x00003e0)>>5)|((color&0x0000001f)<<5);
541                 *backbuffer++=color;
542                 width--;
543         }
544 }
545 //////////////////////////////////////////////////////////////////////////////
546 //
547 //////////////////////////////////////////////////////////////////////////////
548 //
549 //
550 //
551 //
552 //
553 //
554 //////////////////////////////////////////////////////////////////////////////
555 void tom_render_16bpp_cry_rgb_mix_stretch_scanline(int16 *backbuffer)
556 {
557         uint32 chrm, chrl, y;
558
559         uint16 width=tom_width;
560         uint8 *current_line_buffer=(uint8*)&tom_ram_8[0x1800];
561         
562         while (width)
563         {
564                 uint16 color;
565                 color=*current_line_buffer++;
566                 color<<=8;
567                 color|=*current_line_buffer++;
568                 *backbuffer++=tom_cry_rgb_mix_lut[color];
569                 current_line_buffer+=2;
570                 width--;
571         }
572 }
573 //////////////////////////////////////////////////////////////////////////////
574 //
575 //////////////////////////////////////////////////////////////////////////////
576 //
577 //
578 //
579 //
580 //
581 //
582 //////////////////////////////////////////////////////////////////////////////
583 void tom_render_16bpp_cry_stretch_scanline(int16 *backbuffer)
584 {
585         uint32 chrm, chrl, y;
586
587         uint16 width=tom_width;
588         uint8 *current_line_buffer=(uint8*)&tom_ram_8[0x1800];
589         
590         while (width)
591         {
592                 uint16 color;
593                 color=*current_line_buffer++;
594                 color<<=8;
595                 color|=*current_line_buffer++;
596                 
597                 chrm = (color & 0xF000) >> 12;    
598                 chrl = (color & 0x0F00) >> 8;
599                 y    = (color & 0x00FF);
600                                 
601                 uint16 red   =  ((((uint32)redcv[chrm][chrl])*y)>>11);
602                 uint16 green =  ((((uint32)greencv[chrm][chrl])*y)>>11);
603                 uint16 blue  =  ((((uint32)bluecv[chrm][chrl])*y)>>11);
604                 
605                 uint16 color2;
606                 color2=*current_line_buffer++;
607                 color2<<=8;
608                 color2|=*current_line_buffer++;
609                 
610                 chrm = (color2 & 0xF000) >> 12;    
611                 chrl = (color2 & 0x0F00) >> 8;
612                 y    = (color2 & 0x00FF);
613                                 
614                 uint16 red2   = ((((uint32)redcv[chrm][chrl])*y)>>11);
615                 uint16 green2 = ((((uint32)greencv[chrm][chrl])*y)>>11);
616                 uint16 blue2  = ((((uint32)bluecv[chrm][chrl])*y)>>11);
617                 
618                 red=(red+red2)>>1;
619                 green=(green+green2)>>1;
620                 blue=(blue+blue2)>>1;
621
622                 *backbuffer++=(red<<10)|(green<<5)|blue;
623                 width--;
624         }
625 }
626 //////////////////////////////////////////////////////////////////////////////
627 //
628 //////////////////////////////////////////////////////////////////////////////
629 //
630 //
631 //
632 //
633 //
634 //
635 //////////////////////////////////////////////////////////////////////////////
636 void tom_render_24bpp_stretch_scanline(int16 *backbuffer)
637 {
638         uint16 width=tom_width;
639         uint8 *current_line_buffer=(uint8*)&tom_ram_8[0x1800];
640         
641         while (width)
642         {
643                 uint16 green=*current_line_buffer++;
644                 uint16 red=*current_line_buffer++;
645                 uint16 nc=*current_line_buffer++;
646                 uint16 blue=*current_line_buffer++;
647                 red>>=3;
648                 green>>=3;
649                 blue>>=3;
650                 *backbuffer++=(red<<10)|(green<<5)|blue;
651                 current_line_buffer+=4;
652                 width--;
653         }
654 }
655 //////////////////////////////////////////////////////////////////////////////
656 //
657 //////////////////////////////////////////////////////////////////////////////
658 //
659 //
660 //
661 //
662 //
663 //
664 //////////////////////////////////////////////////////////////////////////////
665 void tom_render_16bpp_direct_stretch_scanline(int16 *backbuffer)
666 {
667         uint16 width=tom_width;
668         uint8 *current_line_buffer=(uint8*)&tom_ram_8[0x1800];
669         
670         while (width)
671         {
672                 uint16 color=*current_line_buffer++;
673                 color<<=8;
674                 color|=*current_line_buffer++;
675                 color>>=1;
676                 *backbuffer++=color;
677                 current_line_buffer+=2;
678                 width--;
679         }
680 }
681 //////////////////////////////////////////////////////////////////////////////
682 //
683 //////////////////////////////////////////////////////////////////////////////
684 //
685 //
686 //
687 //
688 //
689 //
690 //////////////////////////////////////////////////////////////////////////////
691 void tom_render_16bpp_rgb_stretch_scanline(int16 *backbuffer)
692 {
693         uint16 width=tom_width;
694         uint8 *current_line_buffer=(uint8*)&tom_ram_8[0x1800];
695         
696         while (width)
697         {
698                 uint16 color1=*current_line_buffer++;
699                 color1<<=8;
700                 color1|=*current_line_buffer++;
701                 color1>>=1;
702                 uint16 color2=*current_line_buffer++;
703                 color2<<=8;
704                 color2|=*current_line_buffer++;
705                 color2>>=1;
706                 uint16 red=(((color1&0x7c00)>>10)+((color2&0x7c00)>>10))>>1;
707                 uint16 green=(((color1&0x00003e0)>>5)+((color2&0x00003e0)>>5))>>1;
708                 uint16 blue=(((color1&0x0000001f))+((color2&0x0000001f)))>>1;
709
710                 color1=(red<<10)|(blue<<5)|green;
711                 *backbuffer++=color1;
712                 width--;
713         }
714 }
715 //////////////////////////////////////////////////////////////////////////////
716 //
717 //////////////////////////////////////////////////////////////////////////////
718 //
719 //
720 //
721 //
722 //
723 //
724 //////////////////////////////////////////////////////////////////////////////
725 void tom_exec_scanline(int16 * backbuffer, int32 scanline, int8 render)
726 {
727         UINT16 bg = GET16(BG);
728         tom_scanline = scanline;
729
730         jaguar_word_write(0xF00004, jaguar_word_read(0xF00004) + 1);
731
732         if (render)
733         {
734                 uint8 * current_line_buffer = (uint8 *)&tom_ram_8[0x1800];
735                 uint16 * current_line_buffer_16 = (uint16 *)current_line_buffer;
736
737                 for(int i=0; i<tom_real_internal_width; i++)
738                         *current_line_buffer_16++ = bg;
739
740                 op_process_list(backbuffer, scanline, render);
741                 
742                 (scanline_render[tom_getVideoMode()])(backbuffer);
743         }
744 }
745 //////////////////////////////////////////////////////////////////////////////
746 //
747 //////////////////////////////////////////////////////////////////////////////
748 //
749 //
750 //
751 //
752 //
753 //
754 //////////////////////////////////////////////////////////////////////////////
755 void tom_init(void)
756 {
757         op_init();
758         blitter_init();
759         pcm_init();
760 //      fprintf(log_get(),"tom_init()\n");
761         memory_malloc_secure((void **)&tom_ram_8, 0x4000, "tom ram");
762 //      tom_ram_16 = (uint16 *)tom_ram_8;
763 //      tom_ram_32 = (uint32 *)tom_ram_8;
764         tom_reset();
765         memcpy(scanline_render, scanline_render_normal, sizeof(scanline_render));
766         tom_calc_cry_rgb_mix_lut();
767 }
768 //////////////////////////////////////////////////////////////////////////////
769 //
770 //////////////////////////////////////////////////////////////////////////////
771 //
772 //
773 //
774 //
775 //
776 //
777 //////////////////////////////////////////////////////////////////////////////
778 uint32 tom_getHBlankWidthInPixels(void)
779 {
780         return hblankWidthInPixels;
781 }
782 //////////////////////////////////////////////////////////////////////////////
783 //
784 //////////////////////////////////////////////////////////////////////////////
785 //
786 //
787 //
788 //
789 //
790 //
791 //////////////////////////////////////////////////////////////////////////////
792 uint32 tom_getVideoModeWidth(void)
793 {
794         static uint16 onetime = 1;
795
796 /*      uint16 vmode = SWAP_16(VMODE);
797         uint16 hdb = SWAP_16(HDB);
798         uint16 hde = SWAP_16(HDE);
799         uint16 hbb = SWAP_16(HBB);
800         uint16 hbe = SWAP_16(HBE);*/
801         uint16 vmode = GET16(VMODE);
802         uint16 hdb = GET16(HDB);
803         uint16 hde = GET16(HDE);
804         uint16 hbb = GET16(HBB);
805         uint16 hbe = GET16(HBE);
806
807         int clock_cycles_per_pixel = ((vmode >> 9) & 0x07);
808
809         uint32 width = 640;
810         switch (clock_cycles_per_pixel)
811         {
812         case 0: width = 640; break;
813         case 1: width = 640; break;
814         case 2: width = 448; break;
815         case 3: width = 320; break;
816         case 4: width = 256; break;
817         case 5: width = 256; break;
818         case 6: width = 256; break;
819         case 7: width = 320; break;
820 //      default: fprintf(log_get(),"%i \n",clock_cycles_per_pixel);
821         }
822         
823         if (jaguar_mainRom_crc32 == 0x3c7bfda8)
824         {
825                 if (width == 320)
826                         width += 80;
827                 if (width == 448)
828                         width -= 16;
829         }
830         if (hdb == 123)
831                 hblankWidthInPixels = 16;
832         else
833                 hblankWidthInPixels = 0;
834
835 //      fprintf(log_get(),"hdb=%i hbe=%i\n",hdb,hbe);
836         return width;
837 }
838 //////////////////////////////////////////////////////////////////////////////
839 //
840 //////////////////////////////////////////////////////////////////////////////
841 //
842 //
843 //
844 //
845 //
846 //
847 //////////////////////////////////////////////////////////////////////////////
848 uint32 tom_getVideoModeHeight(void)
849 {
850 /*      uint16 vmode = SWAP_16(VMODE);
851         uint16 vdb = SWAP_16(VDB);
852         uint16 vde = SWAP_16(VDE);
853         uint16 vbb = SWAP_16(VBB);
854         uint16 vbe = SWAP_16(VBE);*/
855         uint16 vmode = GET16(VMODE);
856         uint16 vdb = GET16(VDB);
857         uint16 vde = GET16(VDE);
858         uint16 vbb = GET16(VBB);
859         uint16 vbe = GET16(VBE);
860         
861         if (vde == 65535)
862                 vde = vbb;
863         
864         uint32 screen_height = (vde/*-vdb*/) >> 1;
865         return 227;//WAS:screen_height);
866 }
867 //////////////////////////////////////////////////////////////////////////////
868 //
869 //////////////////////////////////////////////////////////////////////////////
870 //      
871 //
872 //
873 //
874 //
875 //
876 //////////////////////////////////////////////////////////////////////////////
877 void tom_reset(void)
878 {
879 //      fprintf(log_get(),"tom_reset()\n");
880         op_reset();
881         blitter_reset();
882         pcm_reset();
883
884         memset(tom_ram_8, 0x00, 0x4000);
885 //      tom_ram_8[MEMCON1] = 0x18, tom_ram_8[MEMCON1+1] = 0x61;
886         SET16(MEMCON1, 0x1861);
887 //      tom_ram_8[MEMCON2] = 0x00, tom_ram_8[MEMCON2+1] = 0x00;
888         SET16(MEMCON2, 0x0000);
889 //      tom_ram_8[VMODE] = 0x06, tom_ram_8[VMODE+1] = 0xC1;
890         SET16(VMODE, 0x06C1);
891 //      tom_ram_8[VP] = (523 & 0xFF00) >> 8, tom_ram_8[VP+1] = 523 & 0x00FF; // 525-2
892         SET16(VP, 523);
893 //      tom_ram_8[HP] = SWAP_16(844);
894         SET16(HP, 844);
895 //      tom_ram_8[VS] = SWAP_16(523-6);
896         SET16(VS, 523 - 6);
897 //      tom_ram_8[VBB] = SWAP_16(434);
898         SET16(VBB, 434);
899 //      tom_ram_8[VBE] = SWAP_16(24);
900         SET16(VBE, 24);
901 //      tom_ram_8[HBB] = SWAP_16(689+0x400);
902         SET16(HBB, 689 + 0x400);
903 //      tom_ram_8[HBE] = SWAP_16(125);
904         SET16(HBE, 125);
905
906 //      tom_ram_8[VDE] = SWAP_16(65535);
907         SET16(VDE, 65535);
908 //      tom_ram_8[VDB] = SWAP_16(28);
909         SET16(VDB, 28);
910 //      tom_ram_8[HDB] = SWAP_16(166);
911         SET16(HDB, 166);
912 //      tom_ram_8[HDE] = SWAP_16(65535);
913         SET16(HDE, 65535);
914
915         tom_width = tom_real_internal_width = 0;
916         tom_height = 0;
917         tom_scanline = 0;
918         
919 //      hblankWidthInPixels = (tom_ram_8[HDB] << 8) | tom_ram_8[HDB+1];
920 //      hblankWidthInPixels >>= 1;
921         hblankWidthInPixels = (GET16(HDB)) >> 1;
922
923         tom_puck_int_pending = 0;
924         tom_timer_int_pending = 0;
925         tom_object_int_pending = 0;
926         tom_gpu_int_pending = 0;
927         tom_video_int_pending = 0;
928
929         tom_timer_prescaler = 0;
930         tom_timer_divider = 0;
931         tom_timer_counter = 0;
932         memcpy(scanline_render, scanline_render_normal, sizeof(scanline_render));
933
934 //////////////////////////////////////////////////////////////////////////////
935 //
936 //////////////////////////////////////////////////////////////////////////////
937 //
938 //
939 //
940 //
941 //
942 //
943 //////////////////////////////////////////////////////////////////////////////
944 void tom_done(void)
945 {
946 //      fprintf(log_get(),"tom: done()\n");
947         op_done();
948         pcm_done();
949         blitter_done();
950         fprintf(log_get(), "tom: resolution %ix%i %s\n", tom_getVideoModeWidth(), tom_getVideoModeHeight(),
951                 videoMode_to_str[tom_getVideoMode()]);
952 //      fprintf(log_get(),"\ntom: object processor:\n");
953 //      fprintf(log_get(),"tom: pointer to object list: 0x%.8x\n",op_get_list_pointer());
954 //      fprintf(log_get(),"tom: INT1=0x%.2x%.2x\n",tom_byte_read(0xf000e0),tom_byte_read(0xf000e1));
955         gpu_done();
956         dsp_done();
957         memory_free(tom_ram_8);
958 }
959
960 //
961 // TOM byte access (read)
962 //
963
964 unsigned tom_byte_read(unsigned int offset)
965 {
966         offset &= 0xFF3FFF;
967
968 #ifdef TOM_DEBUG
969         fprintf(log_get(), "TOM: Reading byte at %06X\n", offset);
970 #endif
971
972         if ((offset >= gpu_control_ram_base) && (offset < gpu_control_ram_base+0x20))
973                 return gpu_byte_read(offset);
974         else if ((offset >= gpu_work_ram_base) && (offset < gpu_work_ram_base+0x1000))
975                 return gpu_byte_read(offset);
976         else if ((offset >= 0xF00010) && (offset < 0xF00028))
977                 return op_byte_read(offset);
978         else if ((offset >= 0xF02200) && (offset < 0xF022A0))
979                 return blitter_byte_read(offset);
980         else if (offset == 0xF00050)
981                 return tom_timer_prescaler >> 8;
982         else if (offset == 0xF00051)
983                 return tom_timer_prescaler & 0xFF;
984         else if (offset == 0xF00052)
985                 return tom_timer_divider >> 8;
986         else if (offset == 0xF00053)
987                 return tom_timer_divider & 0xFF;
988
989         return tom_ram_8[offset & 0x3FFF];
990 }
991
992 //
993 // TOM word access (read)
994 //
995
996 unsigned tom_word_read(unsigned int offset)
997 {
998         offset &= 0xFF3FFF;
999 #ifdef TOM_DEBUG
1000         fprintf(log_get(), "TOM: Reading word at %06X\n", offset);
1001 #endif
1002         if (offset == 0xF000E0)
1003         {
1004                 uint16 data = (tom_puck_int_pending << 4) | (tom_timer_int_pending << 3)
1005                         | (tom_object_int_pending << 2) | (tom_gpu_int_pending << 1)
1006                         | (tom_video_int_pending << 0);
1007                 //fprintf(log_get(),"tom: interrupt status is 0x%.4x \n",data);
1008                 return data;
1009         }
1010         else if (offset == 0xF00006)
1011                 return (tom_scanline << 1) + 1;
1012         else if ((offset >= gpu_control_ram_base) && (offset < gpu_control_ram_base+0x20))
1013                 return gpu_word_read(offset);
1014         else if ((offset >= gpu_work_ram_base) && (offset < gpu_work_ram_base+0x1000))
1015                 return gpu_word_read(offset);
1016         else if ((offset >= 0xF00010) && (offset < 0xF00028))
1017                 return op_word_read(offset);
1018         else if ((offset >= 0xF02200) && (offset < 0xF022A0))
1019                 return blitter_word_read(offset);
1020         else if (offset == 0xF00050)
1021                 return tom_timer_prescaler;
1022         else if (offset == 0xF00052)
1023                 return tom_timer_divider;
1024
1025         offset &= 0x3FFF;
1026
1027 //      uint16 data = tom_byte_read(offset);
1028 //      data <<= 8;
1029 //      data |= tom_byte_read(offset+1);
1030
1031 //      return data;
1032         return (tom_byte_read(offset) << 8) | tom_byte_read(offset+1);
1033 }
1034
1035 //
1036 // TOM byte access (write)
1037 //
1038
1039 void tom_byte_write(unsigned offset, unsigned data)
1040 {
1041         offset &= 0xFF3FFF;
1042
1043 #ifdef TOM_DEBUG
1044         fprintf(log_get(), "TOM: Writing byte %02X at %06X\n", data, offset);
1045 #endif
1046
1047         if ((offset >= gpu_control_ram_base) && (offset < gpu_control_ram_base+0x20))
1048         {
1049                 gpu_byte_write(offset, data);
1050                 return;
1051         }
1052         else if ((offset >= gpu_work_ram_base) && (offset < gpu_work_ram_base+0x1000))
1053         {
1054                 gpu_byte_write(offset, data);
1055                 return;
1056         }
1057         else if ((offset >= 0xF00010) && (offset < 0xF00028))
1058         {
1059                 op_byte_write(offset, data);
1060                 return;
1061         }
1062         else if ((offset >= 0xF02200) && (offset < 0xF022A0))
1063         {
1064                 blitter_byte_write(offset, data);
1065                 return;
1066         }
1067         else if (offset == 0xF00050)
1068         {
1069                 tom_timer_prescaler = (tom_timer_prescaler & 0x00FF) | (data << 8);
1070                 tom_reset_timer();
1071                 return;
1072         }
1073         else if (offset == 0xF00051)
1074         {
1075                 tom_timer_prescaler = (tom_timer_prescaler & 0xFF00) | data;
1076                 tom_reset_timer();
1077                 return;
1078         }
1079         else if (offset == 0xF00052)
1080         {
1081                 tom_timer_divider = (tom_timer_divider & 0x00FF) | (data << 8);
1082                 tom_reset_timer();
1083                 return;
1084         }
1085         else if (offset == 0xF00053)
1086         {
1087                 tom_timer_divider = (tom_timer_divider & 0xFF00) | data;
1088                 tom_reset_timer();
1089                 return;
1090         }
1091
1092         tom_ram_8[offset & 0x3FFF] = data;
1093 }
1094
1095 //
1096 // TOM word access (write)
1097 //
1098
1099 void tom_word_write(unsigned offset, unsigned data)
1100 {
1101         offset &= 0xFF3FFF;
1102
1103 #ifdef TOM_DEBUG
1104         fprintf(log_get(), "TOM: Writing word %04X at %06X\n", data, offset);
1105 #endif
1106
1107         if ((offset >= gpu_control_ram_base) && (offset < gpu_control_ram_base+0x20))
1108         {
1109                 gpu_word_write(offset, data);
1110                 return;
1111         }
1112         else if ((offset >= gpu_work_ram_base) && (offset < gpu_work_ram_base+0x1000))
1113         {
1114                 gpu_word_write(offset, data);
1115                 return;
1116         }
1117         else if ((offset >= 0xF00000) && (offset < 0xF00002))
1118         {
1119                 tom_byte_write(offset, (data>>8));
1120                 tom_byte_write(offset+1, (data&0xFF));
1121         }
1122         else if ((offset >= 0xF00010) && (offset < 0xF00028))
1123         {
1124                 op_word_write(offset, data);
1125                 return;
1126         }
1127         else if (offset == 0xF00050)
1128         {
1129                 tom_timer_prescaler = data;
1130                 tom_reset_timer();
1131                 return;
1132         }
1133         else if (offset == 0xF00052)
1134         {
1135                 tom_timer_divider = data;
1136                 tom_reset_timer();
1137                 return;
1138         }
1139         else if (offset == 0xF000E0)
1140         {
1141                 if (data & 0x0100)
1142                         tom_video_int_pending = 0;
1143                 if (data & 0x0200)
1144                         tom_gpu_int_pending = 0;
1145                 if (data & 0x0400)
1146                         tom_object_int_pending = 0;
1147                 if (data & 0x0800)
1148                         tom_timer_int_pending = 0;
1149                 if (data & 0x1000)
1150                         tom_puck_int_pending = 0;
1151         }
1152         else if ((offset >= 0xF02200) && (offset < 0xF022A0))
1153         {
1154                 blitter_word_write(offset, data);
1155                 return;
1156         }
1157
1158         offset &= 0x3FFF;
1159         if (offset == 0x28)
1160                 objectp_running = 1;
1161
1162         tom_byte_write(offset, data >> 8);
1163         tom_byte_write(offset+1,  data & 0xFF);
1164
1165         // detect screen resolution changes
1166         if ((offset >= 0x28) && (offset <= 0x4F))
1167         {
1168                 int width, height;
1169                 tom_real_internal_width = width = tom_getVideoModeWidth();
1170                 height = tom_getVideoModeHeight();
1171                 if (width == 640)
1172                 {
1173                         memcpy(scanline_render, scanline_render_stretch, sizeof(scanline_render));
1174                         width = 320;
1175                 }
1176                 else
1177                 {
1178                         memcpy(scanline_render, scanline_render_normal, sizeof(scanline_render));
1179                 }
1180
1181                 
1182                 if ((width != tom_width) || (height != tom_height))
1183                 {
1184                         ws_audio_done();
1185                 
1186                         static char window_title[256];
1187                         delete surface;
1188                         
1189                         tom_width = width;
1190                         tom_height = height;
1191                         Format format(16, 0x007C00, 0x00003E0, 0x0000001F);
1192                         surface = new Surface(tom_width, tom_height, format);
1193                         console.close();
1194                         sprintf(window_title, "Virtual Jaguar (%ix%i)", tom_width, tom_height);
1195                         console.open(window_title, width, tom_height, format);
1196
1197                         ws_audio_init();
1198                         ws_audio_reset();
1199                 }
1200         }
1201 }
1202 //////////////////////////////////////////////////////////////////////////////
1203 //
1204 //////////////////////////////////////////////////////////////////////////////
1205 //
1206 //
1207 //
1208 //
1209 //
1210 //
1211 //////////////////////////////////////////////////////////////////////////////
1212 int tom_irq_enabled(int irq)
1213 {
1214         return jaguar_byte_read(0xF000E1) & (1 << irq);
1215 }
1216 //////////////////////////////////////////////////////////////////////////////
1217 //
1218 //////////////////////////////////////////////////////////////////////////////
1219 //
1220 //
1221 //
1222 //
1223 //
1224 //
1225 //////////////////////////////////////////////////////////////////////////////
1226 void tom_set_irq_latch(int irq, int enabled)
1227 {
1228         tom_ram_8[0xE0] = (tom_ram_8[0xE0] & (~(1<<irq))) | (enabled ? (1<<irq) : 0);
1229 }
1230 //////////////////////////////////////////////////////////////////////////////
1231 //
1232 //////////////////////////////////////////////////////////////////////////////
1233 //
1234 //
1235 //
1236 //
1237 //
1238 //
1239 //////////////////////////////////////////////////////////////////////////////
1240 uint16 tom_irq_control_reg(void)
1241 {
1242         return (tom_ram_8[0xE0] << 8) | tom_ram_8[0xE1];
1243 }
1244 //////////////////////////////////////////////////////////////////////////////
1245 //
1246 //////////////////////////////////////////////////////////////////////////////
1247 //
1248 //
1249 //
1250 //
1251 //
1252 //
1253 //////////////////////////////////////////////////////////////////////////////
1254 void tom_reset_timer(void)
1255 {
1256         if ((!tom_timer_prescaler) || (!tom_timer_divider))
1257                 tom_timer_counter = 0;
1258         else
1259                 tom_timer_counter = (1 + tom_timer_prescaler) * (1 + tom_timer_divider);
1260 //      fprintf(log_get(),"tom: reseting timer to 0x%.8x (%i)\n",tom_timer_counter,tom_timer_counter);
1261 }
1262 //////////////////////////////////////////////////////////////////////////////
1263 //
1264 //////////////////////////////////////////////////////////////////////////////
1265 //
1266 //
1267 //
1268 //
1269 //
1270 //
1271 //////////////////////////////////////////////////////////////////////////////
1272 void tom_pit_exec(uint32 cycles)
1273 {
1274         if (tom_timer_counter > 0)
1275         {
1276                 tom_timer_counter -= cycles;
1277
1278                 if (tom_timer_counter <= 0)
1279                 {
1280                         tom_set_pending_timer_int();
1281                         gpu_set_irq_line(2, 1);
1282                         if ((tom_irq_enabled(IRQ_TIMER)) && (jaguar_interrupt_handler_is_valid(64)))
1283                         {
1284 //                              s68000interrupt(7, 64);
1285 //                              s68000flushInterrupts();
1286                                 m68k_set_irq(7);                                // Cause a 68000 NMI...
1287                         }
1288                         tom_reset_timer();
1289                 }
1290         }
1291 }