]> Shamusworld >> Repos - virtualjaguar/blob - src/objectp.cpp
This commit was generated by cvs2svn to compensate for changes in r8,
[virtualjaguar] / src / objectp.cpp
1 //
2 // Object Processor
3 //
4 // by cal2
5 // GCC/SDL port by Niels Wagenaar (Linux/WIN32) and Caz (BeOS)
6 // Cleanups by James L. Hammons
7 //
8
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include "jaguar.h"
13
14 //#define OP_DEBUG
15 //#define OP_DEBUG_BMP
16 //WTFITF???static int cnt = 0;
17 extern uint32 jaguar_mainRom_crc32;
18
19 static uint8 * op_blend_y;
20 static uint8 * op_blend_cc;
21
22 #define BLEND_Y(dst,src) op_blend_y[(((uint16)dst)<<8) | ((uint16)(src))]
23 #define BLEND_CC(dst,src) op_blend_cc[(((uint16)dst)<<8) | ((uint16)(src))]
24
25 static uint8 objectp_ram[0x40];
26 uint8 objectp_running;
27
28 uint8 objectp_stop_reading_list;
29
30 #define OBJECT_TYPE_BITMAP      0
31 #define OBJECT_TYPE_SCALE       1
32 #define OBJECT_TYPE_GPU         2
33 #define OBJECT_TYPE_BRANCH      3
34 #define OBJECT_TYPE_STOP        4
35 /*
36 #define OBJECT_TYPE_BITMAP      000
37 #define OBJECT_TYPE_SCALE       001
38 #define OBJECT_TYPE_GPU         010
39 #define OBJECT_TYPE_BRANCH      011
40 #define OBJECT_TYPE_STOP        100
41 */
42
43 #define CONDITION_EQUAL                 0
44 #define CONDITION_LESS_THAN             1
45 #define CONDITION_GREATER_THAN  2
46 #define CONDITION_OP_FLAG_SET   3
47 #define CONDITION_SECOND_HALF_LINE      4
48
49 #define FLAGS_RELEASE           8
50 #define FLAGS_TRANSPARENT       4
51 #define FLAGS_READMODIFY        2
52 #define FLAGS_HFLIP                     1
53
54 static uint8 op_bitmap_bit_depth[8] = { 1, 2, 4, 8, 16, 24, 32, 0 };
55 static uint32 op_bitmap_bit_size[8] =
56         { (uint32)(0.125*65536), (uint32)(0.25*65536), (uint32)(0.5*65536), (uint32)(1*65536),
57           (uint32)(2*65536),     (uint32)(1*65536),    (uint32)(1*65536),   (uint32)(1*65536) };
58 static uint32 op_pointer;
59 //WTFITF???static int cnt_bitmap = 0;
60
61 //
62 // Object Processor bitmap processing
63 //
64
65 void op_process_bitmap(int16 * backbuffer, int scanline, uint64 p0, uint64 p1, int render)
66 {
67         uint8 bitdepth = (p1 >> 12) & 0x07;
68         int16 ypos = ((p0 >> 3) & 0x3FF) / 2;                   // ??? What if not interlaced (/2)?
69         int32 xpos = (((int32)((p1 << 20) & 0xFFFFFFFF)) >> 20) - tom_getHBlankWidthInPixels();
70         int32 iwidth = ((p1 >> 28) & 0x3FF) * 4;
71         int32 dwidth = ((p1 >> 18) & 0x3FF) * 4;                // ??? Should it be signed or unsigned ???
72         int16 height = ((p0 >> 14) & 0x3FF) - 1;
73         uint32 link = ((p0 >> 24) & 0x7FFFF) << 3;
74         uint32 ptr = ((p0 >> 43) & 0x1FFFFF) << 3;
75 #ifdef OP_DEBUG_BMP
76         uint32  firstPix = (p1 >> 49) & 0x3F;
77 #endif
78         uint8 flags = (p1 >> 45) & 0x0F;
79         uint8 idx = (p1 >> 38) & 0x7F;
80         uint32 pitch = (p1 >> 15) & 0x07;
81         int16 scanline_width = tom_getVideoModeWidth();
82         uint8 * tom_ram_8 = tom_get_ram_pointer();
83         uint8 * current_line_buffer = &tom_ram_8[0x1800];
84         uint8 * paletteRam = &tom_ram_8[0x400];
85         uint8 doom_hack = 0;
86
87 //if (scanline == 200)
88 //      fprintf(log_get(), "OP --> Current OPPtr: %08X, next: %08X, BMPPtr: %08X\n", op_pointer, link, ptr);
89
90         op_pointer = link;
91
92         if (!render || (op_pointer == 0) || (height < 0) || (dwidth < 0) || (ptr == 0) || (pitch == 0))
93                 return;
94
95         if (iwidth == 0)
96                 dwidth = iwidth = height;
97
98         if (jaguar_mainRom_crc32 == 0x5e705756) // doom
99         {
100                 if ((iwidth==160)&&(height==179)&&(xpos==-9)&&(ypos==24))
101                 {
102                         doom_hack=1;
103                         xpos=0;
104                 }
105         }
106         // il y a un offset vertical de 20 pour un des bitmaps
107         // dans dinon olympics pour une raison encore inconnue
108         if (jaguar_mainRom_crc32==0x3c7bfda8)
109         {
110                 if ((iwidth==220)&&(height==184)&&(ypos==0))
111                 {
112                         ypos=20;
113                 }
114         }
115         else
116         if (jaguar_mainRom_crc32==0x2f032271)
117         {
118                 ypos+=8;
119         }
120         if (op_bitmap_bit_depth[bitdepth] == 24)
121         {
122                 iwidth *= 2;
123                 dwidth *= 2;
124         }
125         if (op_bitmap_bit_depth[bitdepth] == 8)
126         {
127                 iwidth *= 2;
128                 dwidth *= 2;
129         }
130         if (op_bitmap_bit_depth[bitdepth] == 4)
131         {
132                 iwidth *= 2;
133                 dwidth *= 2;
134         }
135         if (op_bitmap_bit_depth[bitdepth] == 2)
136         {
137                 iwidth *= 2;
138                 dwidth *= 2;
139         }
140         if (op_bitmap_bit_depth[bitdepth] == 1)
141         {
142                 iwidth *= 2;
143                 dwidth *= 2;
144         }
145         // Power Drive Rally (fixed size bitmaps have a 240 lines vertical offset)
146         // but could well be a modulo 240
147         if (jaguar_mainRom_crc32==0x0ab88d90)
148                 ypos %= 240;
149
150 #ifdef OP_DEBUG_BMP
151         fprintf(log_get(),"bitmap %ix%i %ibpp at %i,%i firstpix=%i ptr=0x%.8x pitch %i hflipped=%s dwidth=%i (linked to 0x%.8x) Transluency=%s\n",iwidth,height,op_bitmap_bit_depth[bitdepth],xpos,ypos,firstPix,ptr,pitch,flags&FLAGS_HFLIP?"yes":"no",dwidth,op_pointer,(flags&FLAGS_READMODIFY)?"yes":"no");
152 #endif
153
154         if ((scanline < ypos) || (scanline > (ypos + height)))
155                 return;
156
157         // seek to the good bitmap scanline
158         // not sure for palettized modes
159         if (op_bitmap_bit_depth[bitdepth] > 8)
160                 ptr += ((dwidth * op_bitmap_bit_size[bitdepth]) >> 16) * (scanline - ypos);
161         else
162                 ptr += dwidth * (scanline - ypos);
163
164         if (xpos < 0)
165         {
166                 iwidth += xpos;
167                 ptr += (pitch * op_bitmap_bit_size[bitdepth] * (-xpos)) >> 16;
168                 xpos = 0;
169         }
170
171         if (iwidth <= 0)
172         {
173 #ifdef OP_DEBUG_BMP
174                 fprintf(log_get(), "not rendering because iwidth <= 0\n");
175 #endif
176                 return;
177         }
178         
179         if (flags & FLAGS_HFLIP)
180         {
181                 if ((xpos < 0) || ((xpos - iwidth) >= scanline_width))
182                         return;
183
184                 if ((xpos - iwidth) < 0)
185                         iwidth = xpos;
186         }
187         else
188         {
189                 if (((xpos + iwidth) < 0) || (xpos >= scanline_width))
190                         return;
191
192                 if ((xpos + iwidth) > scanline_width)
193                         iwidth = scanline_width - xpos;
194         }
195
196         current_line_buffer += xpos * 2; // 2 in 16 bpp modes (need to take the mode into account)
197
198         // doom switches the resolution from 320 to 160 to double the display width
199         // this is not yet supported
200         if (doom_hack)
201         {
202                 while (iwidth)
203                 {
204                         uint8 d0=jaguar_byte_read(ptr+0);
205                         uint8 d1=jaguar_byte_read(ptr+1);
206                         *current_line_buffer++=d0;
207                         *current_line_buffer++=d1;
208                         *current_line_buffer++=d0;
209                         *current_line_buffer++=d1;
210                         ptr+=2;
211                         iwidth--;
212                 }
213                 return;
214         }
215         if (op_bitmap_bit_depth[bitdepth] == 1)
216         {
217                 if (pitch == 1)
218                 {
219 #include "fbmpop1.h"
220                 }
221                 else
222                 {
223 #include "fbmpop1p.h"
224                 }
225         }
226         else if (op_bitmap_bit_depth[bitdepth] == 2)
227         {
228                 if (pitch == 1)
229                 {
230 #include "fbmpop2.h"
231                 }
232                 else
233                 {
234 #include "fbmpop2p.h"
235                 }
236         }
237         else if (op_bitmap_bit_depth[bitdepth] == 4)
238         {
239                 if (pitch == 1)
240                 {
241 #include "fbmpop4.h"
242                 }
243                 else
244                 {
245 #include "fbmpop4p.h"
246                 }
247         }
248         else if (op_bitmap_bit_depth[bitdepth] == 8)
249         {
250                 if (pitch == 1)
251                 {
252 #include "fbmpop8.h"
253                 }
254                 else
255                 {
256 #include "fbmpop8p.h"
257                 }
258         }
259         else if (op_bitmap_bit_depth[bitdepth] == 16)
260         {
261                 if (pitch == 1)
262                 {
263 #include "fbmpop16.h"
264                 }
265                 else
266                 {
267 #include "fbmpop16p.h"
268                 }
269         }
270         else if (op_bitmap_bit_depth[bitdepth] == 24)
271         {
272                 if (pitch == 1)
273                 {
274 #include "fbmpop24.h"
275                 }
276                 else
277                 {
278 #include "fbmpop24p.h"
279                 }
280         }
281 }
282
283 //
284 // Object Processor scaled bitmap processing
285 //
286
287 void op_process_scaled_bitmap(int16 * backbuffer, int scanline, uint64 p0, uint64 p1, uint64 p2, int render)
288 {
289 //      if ((render == 0) || (op_pointer == 0) || (height < 0) || (dwidth < 0) || (ptr == 0) || (pitch == 0))
290
291         int32 xpos = (((int32)((p1 << 20) & 0xFFFFFFFF)) >> 20) - tom_getHBlankWidthInPixels();
292         int16 ypos = ((p0 & 0x3FF8) >> 3) / 2;
293         uint16 iwidth = ((p1 >> 28) & 0x3FF) * 4;
294         int16 dwidth = ((p1 >> 18) & 0x3FF) * 4;                // ??? Signed or unsigned ???
295         int16 height = (p0 >> 14) & 0x3FF;                              // ??? Signed or unsigned ???
296         uint32 link = ((p0 >> 24) & 0x7FFFF) << 3;
297         uint32 ptr = ((p0 >> 43) & 0x1FFFFF) << 3;
298 //unused        uint32 firstPix = (p1 >> 49) & 0x3F;
299         uint8 flags = (p1 >> 45) & 0x0F;
300         uint8 idx = (p1 >> 38) & 0x7F;
301         uint8 pitch = (p1 >> 15) & 0x07;
302         uint8 bitdepth = (p1 >> 12) & 0x07;
303         int16 scanline_width = tom_getVideoModeWidth();
304         uint8 * tom_ram_8 = tom_get_ram_pointer();
305         uint8 * current_line_buffer = &tom_ram_8[0x1800];
306         uint32 vscale_fixed3p5 = ((p2 >> 8) & 0xFF);
307         uint32 hscale_fixed3p5 = (p2 & 0xFF);
308         float vscale = (float)vscale_fixed3p5 / 32.0f, hscale = (float)hscale_fixed3p5 / 32.0f;
309
310         op_pointer = link;
311
312         if (jaguar_mainRom_crc32==0x5a5b9c68) // atari karts
313         {
314                 if (vscale == 0.0f) 
315                         vscale = 1.0f;
316
317                 if (ypos == 0)
318                         ypos = scanline;
319         }
320 #ifdef OP_DEBUG_BMP
321         if (xpos == -3)
322                 fprintf(log_get(), "[scanline %i] %ix%i scaled to %ix%i scale (%f, %f)%i bpp pitch %i at (%i,%i) @ 0x%.8x Transluency=%s\n",
323                         scanline, iwidth,height, (int)(iwidth*hscale), (int)(height*vscale), hscale, vscale,
324                         op_bitmap_bit_depth[bitdepth], pitch, xpos, ypos, ptr, (flags&FLAGS_READMODIFY) ? "yes" : "no");
325 #endif
326         if (jaguar_mainRom_crc32==0x2f032271)
327                 ypos += 8;
328
329         if ((render == 0) || (op_pointer == 0) || (height < 0) || (dwidth < 0) || (ptr == 0) || (pitch == 0))
330                 return;
331
332         if (op_bitmap_bit_depth[bitdepth]==8)
333         {
334                 iwidth*=2;
335                 dwidth*=2;
336         }
337         if (op_bitmap_bit_depth[bitdepth]==4)
338         {
339                 iwidth*=2;
340                 dwidth*=2;
341         }
342         if (op_bitmap_bit_depth[bitdepth]==2)
343         {
344                 iwidth*=2;
345                 dwidth*=2;
346         }
347         if (op_bitmap_bit_depth[bitdepth]==1)
348         {
349                 iwidth*=2;
350                 dwidth*=2;
351         }
352
353         uint16 scaled_width = (uint16)((float)iwidth * hscale),
354                 scaled_height = (uint16)((float)height * vscale);
355
356         if (op_bitmap_bit_depth[bitdepth] == 4) // why ?
357                 scaled_width *= 2;
358
359         if (op_bitmap_bit_depth[bitdepth] == 2) // why ?
360                 scaled_width *= 4;
361
362         if (op_bitmap_bit_depth[bitdepth] == 1) // why ?
363                 scaled_width *= 8;
364
365         // seek to the good bitmap scanline
366         // not sure for palettized modes
367         if (op_bitmap_bit_depth[bitdepth] > 8)
368                 ptr += ((dwidth * op_bitmap_bit_size[bitdepth]) >> 16) * ((uint32)((scanline - ypos) / vscale));
369         else
370                 ptr += dwidth * ((uint32)((scanline - ypos) / vscale));
371
372         // visible ?
373         if ((scanline < ypos) || (scanline > (ypos+scaled_height)) || ((xpos+scaled_width) < 0)
374                 || (xpos >= scanline_width))
375                 return;
376         
377         if (xpos < 0)
378         {
379                 scaled_width += xpos;
380                 ptr += (pitch * op_bitmap_bit_size[bitdepth] * ((uint32)((-xpos) / hscale))) >> 16;
381                 xpos = 0;
382         }
383
384         if (iwidth<=0)
385                 return;
386
387         if (flags&FLAGS_HFLIP)
388         {
389                 if ((xpos<0)||((xpos-scaled_width)>=scanline_width))
390                         return;
391
392                 if ((xpos-scaled_width)<0)
393                         scaled_width=xpos;
394         }
395         else
396         {
397                 if (((xpos+scaled_width)<0)||(xpos>=scanline_width))
398                         return;
399
400                 if ((xpos+scaled_width)>scanline_width)
401                         scaled_width=scanline_width-xpos;
402         }
403         
404         current_line_buffer += xpos * 2;
405
406         int32 hscale_fixed = (int32)(65536.0f / hscale);
407         int32 cnt = 0;
408
409         if (op_bitmap_bit_depth[bitdepth] == 1)
410         {
411                 if (pitch == 1)
412                 {
413 #include "zbmpop1.h"
414                 }
415                 else
416                 {
417 #include "zbmpop1p.h"
418                 }
419         }
420         else if (op_bitmap_bit_depth[bitdepth] == 2)
421         {
422                 if (pitch == 1)
423                 {
424 #include "zbmpop2.h"
425                 }
426                 else
427                 {
428 #include "zbmpop2p.h"
429                 }
430         }
431         else if (op_bitmap_bit_depth[bitdepth] == 4)
432         {
433                 if (pitch == 1)
434                 {
435 #include "zbmpop4.h"
436                 }
437                 else
438                 {
439 #include "zbmpop4p.h"
440                 }
441         }
442         else if (op_bitmap_bit_depth[bitdepth] == 8)
443         {
444                 if (pitch == 1)
445                 {
446 #include "zbmpop8.h"
447                 }
448                 else
449                 {
450 #include "zbmpop8p.h"
451                 }
452         }
453         else if (op_bitmap_bit_depth[bitdepth] == 16)
454         {
455                 if (pitch == 1)
456                 {
457 #include "zbmpop16.h"
458                 }
459                 else
460                 {
461 #include "zbmpop16p.h"
462                 }
463         }
464         else
465                 fprintf(log_get(),"(unimplemented) %i bpp scaled bitmap\n",op_bitmap_bit_depth[bitdepth]);
466 }
467
468 uint64 op_load_phrase(uint32 offset)
469 {
470         offset &= ~0x07;                                                // 8 byte alignment
471         return ((uint64)jaguar_long_read(offset) << 32) | (uint64)jaguar_long_read(offset+4);
472 }
473
474 //
475 // Object Processor main list processing
476 //
477
478 void op_process_list(int16 * backbuffer, int scanline, int render)
479 {
480 //      char * condition_to_str[8] =
481 //              { "==", "<", ">", "(opflag set)", "(second half line)", "?", "?", "?" };
482 //WTFITF???     cnt_bitmap = 0;
483
484         if (scanline < tom_get_vdb())
485                 return;
486
487         if (scanline >= 525)//tom_getVideoModeHeight()+tom_get_vdb())
488                 return;
489
490         op_pointer = op_get_list_pointer();
491
492         objectp_stop_reading_list = 0;
493 //WTFITF???     cnt = 0;
494
495 //      if (op_pointer) fprintf(log_get()," new op list at 0x%.8x scanline %i\n",op_pointer,scanline);
496         while (op_pointer)
497         {
498                 if (objectp_stop_reading_list)
499                         return;
500                         
501                 uint64 p0 = op_load_phrase(op_pointer);
502                 op_pointer += 8;
503 /*if (scanline == tom_get_vdb())
504 {
505 fprintf(log_get(), "%08X --> phrase %08X %08X", op_pointer - 8, (int)(p0>>32), (int)(p0&0xFFFFFFFF));
506 if ((p0 & 0x07) == OBJECT_TYPE_BITMAP)
507 {
508 fprintf(log_get(), " (BITMAP) ");
509 uint64 p1 = op_load_phrase(op_pointer);
510 fprintf(log_get(), "\n%08X --> phrase %08X %08X ", op_pointer, (int)(p1>>32), (int)(p1&0xFFFFFFFF));
511         uint8 bitdepth = (p1 >> 12) & 0x07;
512         int16 ypos = ((p0 >> 3) & 0x3FF);                       // ??? What if not interlaced (/2)?
513 //      int32 xpos = (((int32)((p1 << 20) & 0xFFFFFFFF)) >> 20);
514 int32 xpos = p1 & 0xFFF;
515 xpos = (xpos & 0x800 ? xpos | 0xFFFFF000 : xpos);
516         uint32 iwidth = ((p1 >> 28) & 0x3FF);
517         uint32 dwidth = ((p1 >> 18) & 0x3FF);           // ??? Should it be signed or unsigned ???
518         int16 height = ((p0 >> 14) & 0x3FF) - 1;
519         uint32 link = ((p0 >> 24) & 0x7FFFF) << 3;
520         uint32 ptr = ((p0 >> 43) & 0x1FFFFF) << 3;
521         uint32 firstPix = (p1 >> 49) & 0x3F;
522         uint8 flags = (p1 >> 45) & 0x0F;
523         uint8 idx = (p1 >> 38) & 0x7F;
524         uint32 pitch = (p1 >> 15) & 0x07;
525 fprintf(log_get(), "[%u (%u) x %u @ %i, %u (%u bpp), l: %08X, p: %08X fp: %02X, fl:%02X, idx:%02X, pt:%02X]\n", iwidth, dwidth, height, xpos, ypos, op_bitmap_bit_depth[bitdepth], link, ptr, firstPix, flags, idx, pitch);
526 uint8 * jaguar_mainRam = GetRamPtr();
527 fprintf(log_get(), "[RAM] --> ");
528 for(int k=0; k<16; k++)
529         fprintf(log_get(), "%02X ", jaguar_mainRam[op_pointer-8 + k]);
530 fprintf(log_get(), "\n");
531 }
532 if ((p0 & 0x07) == OBJECT_TYPE_SCALE)
533 {
534 fprintf(log_get(), " (SCALED BITMAP)\n");
535 }
536 if ((p0 & 0x07) == OBJECT_TYPE_GPU)
537 fprintf(log_get(), " (GPU)\n");
538 if ((p0 & 0x07) == OBJECT_TYPE_BRANCH)
539 {
540 fprintf(log_get(), " (BRANCH)\n");
541 uint8 * jaguar_mainRam = GetRamPtr();
542 fprintf(log_get(), "[RAM] --> ");
543 for(int k=0; k<8; k++)
544         fprintf(log_get(), "%02X ", jaguar_mainRam[op_pointer-8 + k]);
545 fprintf(log_get(), "\n");
546 }
547 if ((p0 & 0x07) == OBJECT_TYPE_STOP)
548 fprintf(log_get(), "    --> List end\n");
549 }*/
550                 
551 //              fprintf(log_get(),"0x%.8x type %i\n",op_pointer,((uint8)p0&0x07));              
552                 switch ((uint8)p0 & 0x07)
553                 {
554                 case OBJECT_TYPE_BITMAP:
555                 {
556                         uint64 p1 = op_load_phrase(op_pointer);
557                         op_pointer += 8;
558                         op_process_bitmap(backbuffer, scanline, p0, p1, render);
559                         break;
560                 }
561                 case OBJECT_TYPE_SCALE:
562                 {
563                         uint64 p1 = op_load_phrase(op_pointer);
564                         op_pointer += 8;
565                         uint64 p2 = op_load_phrase(op_pointer);
566                         op_pointer += 8;
567                         op_process_scaled_bitmap(backbuffer, scanline, p0, p1, p2, render);
568                         break;
569                 }
570                 case OBJECT_TYPE_GPU:
571                 {
572 //unused                        uint64 data = p0 >> 3;
573                         op_set_current_object(p0);
574                         gpu_set_irq_line(3, 1); 
575                         break;
576                 }
577                 case OBJECT_TYPE_BRANCH:
578                 {
579                         uint16 vcnt = (p0 >> 3) & 0x7FF;
580                         uint8  cc   = (p0 >> 14) & 0x03;
581                         uint32 link = ((p0 >> 24) & 0x1FFFFF) << 3;
582                         
583 //                      if ((vcnt!=507)&&(vcnt!=25))
584 //                              fprintf(log_get(),"\t%i%s%i link=0x%.8x\n",scanline,condition_to_str[cc],vcnt>>1,link);
585                         switch (cc)
586                         {
587                         case CONDITION_EQUAL:
588                                 if ((vcnt != 0x7FF) && (vcnt & 0x01))
589                                         vcnt ^= 0x01;
590                                 if (((2 * tom_get_scanline()) == vcnt) || (vcnt == 0x7FF))
591                                         op_pointer = link;
592                                 break;
593                         case CONDITION_LESS_THAN:
594                                 if ((2 * tom_get_scanline()) < vcnt)
595                                         op_pointer = link;
596                                 break;
597                         case CONDITION_GREATER_THAN:
598                                 if ((2 * tom_get_scanline()) > vcnt)
599                                         op_pointer = link;
600                                 break;
601                         case CONDITION_OP_FLAG_SET:
602                                 if (op_get_status_register() & 0x01)
603                                         op_pointer = link;
604                                 break;
605                         case CONDITION_SECOND_HALF_LINE:
606                                 fprintf(log_get(), "op: unexpected CONDITION_SECOND_HALF_LINE in BRANCH object\nop: shuting down\n");
607                                 fclose(log_get());
608                                 exit(0);
609                                 break;
610                         default:
611                                 fprintf(log_get(),"op: unimplemented branch condition %i\n", cc);
612                         }
613                         break;
614                 }
615                 case OBJECT_TYPE_STOP:
616                 {
617                         // unsure
618                         op_set_status_register(((p0>>3) & 0xFFFFFFFF));
619                         
620                         if (p0 & 0x8)
621                         {
622                                 tom_set_pending_object_int();
623                                 if ((tom_irq_enabled(2)) && (jaguar_interrupt_handler_is_valid(64)))
624                                 {
625 //                                      s68000interrupt(7,64);
626 //                                      s68000flushInterrupts();
627                                         m68k_set_irq(7);                                // Cause an NMI to occur...
628                                 }
629                         }
630
631                         return;
632                         break;
633                 }
634                 default:
635                         fprintf(log_get(),"op: unknown object type %i\n", ((uint8)p0 & 0x07)); 
636                         return;
637                 }
638         }
639 }
640
641 //
642 // Object Processor initialization
643 //
644
645 void op_init(void)
646 {
647         memory_malloc_secure((void **)&op_blend_y, 0x10000, "Jaguar Object processor Y blend lookup table");
648         memory_malloc_secure((void **)&op_blend_cc, 0x10000, "Jaguar Object processor C blend lookup table");
649
650         for(int i=0; i<256*256; i++)
651         {
652                 int y = (i >> 8) & 0xFF;
653                 int dy = (int8)(i & 0xFF);
654                 y += dy;
655                 if (y < 0)
656                         y = 0;
657                 else if (y > 0xFF)
658                         y = 0xFF;
659                 op_blend_y[i] = y;
660         }
661
662         for(int i=0; i<256*256; i++)
663         {
664                 int cl = (i >> 8) & 0xFF;
665                 int dcl = (int8)(i & 0xFF);
666                 cl += dcl;
667                 if (cl < 0)
668                         cl = 0;
669                 else if (cl > 0xFF)
670                         cl = 0xFF;
671                 op_blend_cc[i] = cl;
672         }
673         op_reset();
674 }
675
676 //
677 // Object Processor reset
678 //
679
680 void op_reset(void)
681 {
682         memset(objectp_ram, 0x00, 0x40);
683         objectp_running = 0;
684 }
685
686 void op_done(void)
687 {
688 }
689
690 void op_byte_write(uint32 offset, uint8 data)
691 {
692         offset &= 0x3F;
693         objectp_ram[offset] = data;
694 }
695
696 void op_word_write(uint32 offset, uint16 data)
697 {
698         offset &= 0x3F;
699         objectp_ram[offset] = (data >> 8) & 0xFF;
700         objectp_ram[offset+1] = data & 0xFF;
701
702 /*if (offset == 0x20)
703 fprintf(log_get(), "OP: Setting lo list pointer: %04X\n", data);
704 if (offset == 0x22)
705 fprintf(log_get(), "OP: Setting hi list pointer: %04X\n", data);//*/
706 }
707
708 // Memory range: F00010 - F00027
709
710 uint8 op_byte_read(uint32 offset)
711 {
712         offset &= 0x3F;
713         return objectp_ram[offset];
714 }
715
716 uint16 op_word_read(uint32 offset)
717 {
718         return (objectp_ram[offset & 0x3F] << 8) | objectp_ram[(offset+1) & 0x3F];
719 }
720
721 //      F00010-F00017   R     xxxxxxxx xxxxxxxx   OB - current object code from the graphics processor
722 //      F00020-F00023     W   xxxxxxxx xxxxxxxx   OLP - start of the object list
723 //      F00026            W   -------- -------x   OBF - object processor flag
724
725 uint32 op_get_list_pointer(void)
726 {
727         // Note: This register is WORD swapped, hence the funky look of this...
728 /*      uint32 ptr = objectp_ram[0x22];
729         ptr <<= 8;
730         ptr |= objectp_ram[0x23];
731         ptr <<= 8;
732         ptr |= objectp_ram[0x20];
733         ptr <<= 8;
734         ptr |= objectp_ram[0x21];
735 fprintf(log_get(), "OP: Getting list pointer: %08X\n", (unsigned int)ptr);
736         ptr &= ~0x07;
737
738         return ptr;//*/
739         return (objectp_ram[0x22] << 24) | (objectp_ram[0x23] << 16) | (objectp_ram[0x20] << 8) | objectp_ram[0x21];
740 }
741
742 uint32 op_get_status_register(void)
743 {
744 /*      uint32 ptr = objectp_ram[0x26];
745         ptr <<= 8;
746         ptr |= objectp_ram[0x27];
747         ptr <<= 8;
748         ptr |= objectp_ram[0x28];
749         ptr <<= 8;
750         ptr |= objectp_ram[0x29];
751
752         return ptr;//*/
753         return (objectp_ram[0x26] << 24) | (objectp_ram[0x27] << 16) | (objectp_ram[0x28] << 8) | objectp_ram[0x29];
754 }
755
756 void op_set_status_register(uint32 data)
757 {
758         objectp_ram[0x26] = (data & 0xFF000000) >> 24;
759         objectp_ram[0x27] = (data & 0x00FF0000) >> 16;
760         objectp_ram[0x28] = (data & 0x0000FF00) >> 8;
761         objectp_ram[0x29] |= (data & 0xFE);
762 }
763
764 void op_set_current_object(uint64 object)
765 {
766 /*
767  32       28        24        20       16       12        8        4        0
768   +--------^---------^---------^--------^--------^--------^--------^--------+
769 0 |                                object-data                              |
770   +-------------------------------------------------------------------------+
771
772  64       60        56        52       48       44       40       36        32
773   +--------^---------^---------^--------^--------^--------^--------^--------+
774 1 |                                object-data                              |
775   +-------------------------------------------------------------------------+
776 */
777         // Stored as least significant 32 bits first, ms32 last in big endian
778         objectp_ram[0x13] = object & 0xFF; object >>= 8;
779         objectp_ram[0x12] = object & 0xFF; object >>= 8;
780         objectp_ram[0x11] = object & 0xFF; object >>= 8;
781         objectp_ram[0x10] = object & 0xFF; object >>= 8;
782
783         objectp_ram[0x17] = object & 0xFF; object >>= 8;
784         objectp_ram[0x16] = object & 0xFF; object >>= 8;
785         objectp_ram[0x15] = object & 0xFF; object >>= 8;
786         objectp_ram[0x14] = object & 0xFF; 
787 }