11 extern uint32 jaguar_mainRom_crc32;
13 static uint8 * op_blend_y;
14 static uint8 * op_blend_cc;
16 #define BLEND_Y(dst,src) op_blend_y[(((uint16)dst)<<8) | ((uint16)(src))]
17 #define BLEND_CC(dst,src) op_blend_cc[(((uint16)dst)<<8) | ((uint16)(src))]
20 static uint8 objectp_ram[0x40];
21 uint8 objectp_running;
23 uint8 objectp_stop_reading_list;
25 #define OBJECT_TYPE_BITMAP 0
26 #define OBJECT_TYPE_SCALE 1
27 #define OBJECT_TYPE_GPU 2
28 #define OBJECT_TYPE_BRANCH 3
29 #define OBJECT_TYPE_STOP 4
31 #define CONDITION_EQUAL 0
32 #define CONDITION_LESS_THAN 1
33 #define CONDITION_GREATER_THAN 2
34 #define CONDITION_OP_FLAG_SET 3
35 #define CONDITION_SECOND_HALF_LINE 4
37 #define FLAGS_RELEASE 8
38 #define FLAGS_TRANSPARENT 4
39 #define FLAGS_READMODIFY 2
43 static char * condition_to_str[8] = {"==","<",">","(opflag set)","(second half line)","?","?","?"};
45 static uint8 op_bitmap_bit_depth[8]={1, 2, 4, 8, 16, 24, 32, 0 };
46 static uint32 op_bitmap_bit_size[8]={0.125*65536, 0.25*65536, 0.5*65536, 1*65536, 2*65536, 1*65536, 1*65536, 1*65536};
47 static uint32 op_pointer;
48 static int cnt_bitmap = 0;
50 //////////////////////////////////////////////////////////////////////////////
52 //////////////////////////////////////////////////////////////////////////////
56 //////////////////////////////////////////////////////////////////////////////
57 void op_process_bitmap(int16 *backbuffer, int scanline, uint64 p0, uint64 p1, int render)
59 uint8 bitdepth=(p1>>12)&0x07;
61 int16 ypos=(((p0>>3)&0x3ff)/2);
62 int32 xpos=(((int32)((p1<<20)&0xffffffff))>>20)-tom_getHBlankWidthInPixels();
63 int32 iwidth=((p1>>28)&0x3ff)*4;
64 uint32 dwidth=((p1>>18)&0x3ff)*4;
65 int16 height=((p0>>14)&0x3ff)-1;
66 uint32 link=((p0>>24)&0x7ffff)<<3;
67 uint32 ptr=(((p0>>43)&0x1fffff)<<3);
68 uint32 firstPix=(p1>>49)&0x3f;
69 uint8 flags=(p1>>45)&0x0f;
70 uint8 idx=(p1>>38)&0x7f;
71 uint32 pitch=(p1>>15)&0x07;
72 int16 scanline_width=tom_getVideoModeWidth();
73 uint8 *tom_ram_8=tom_get_ram_pointer();
74 uint8 *current_line_buffer=&tom_ram_8[0x1800];
75 uint8 *paletteRam=&tom_ram_8[0x400];
80 if ((!render)||(op_pointer==0)||(height<0)||(dwidth<0)||(ptr==0)||(pitch==0))
88 if (jaguar_mainRom_crc32==0x5e705756) // doom
90 if ((iwidth==160)&&(height==179)&&(xpos==-9)&&(ypos==24))
96 // il y a un offset vertical de 20 pour un des bitmaps
97 // dans dinon olympics pour une raison encore inconnue
98 if (jaguar_mainRom_crc32==0x3c7bfda8)
100 if ((iwidth==220)&&(height==184)&&(ypos==0))
106 if (jaguar_mainRom_crc32==0x2f032271)
110 if (op_bitmap_bit_depth[bitdepth]==24)
115 if (op_bitmap_bit_depth[bitdepth]==8)
120 if (op_bitmap_bit_depth[bitdepth]==4)
125 if (op_bitmap_bit_depth[bitdepth]==2)
130 if (op_bitmap_bit_depth[bitdepth]==1)
135 // Power Drive Rally (fixed size bitmaps have a 240 lines vertical offset)
136 // but could well be a modulo 240
137 if (jaguar_mainRom_crc32==0x0ab88d90)
142 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");
145 if ((scanline<ypos)||(scanline>(ypos+height)))
149 // seek to the good bitmap scanline
150 // not sure for palettized modes
151 if (op_bitmap_bit_depth[bitdepth] > 8)
153 ptr += ((dwidth * op_bitmap_bit_size[bitdepth]) >> 16) * (scanline - ypos);
156 ptr += dwidth * (scanline - ypos);
161 ptr += (pitch * op_bitmap_bit_size[bitdepth] * (-xpos)) >> 16;
168 fprintf(log_get(),"not rendering because iwidth<0\n");
173 if (flags&FLAGS_HFLIP)
175 if ((xpos<0)||((xpos-iwidth)>=scanline_width))
183 if (((xpos+iwidth)<0)||(xpos>=scanline_width))
186 if ((xpos+iwidth)>scanline_width)
187 iwidth=scanline_width-xpos;
191 current_line_buffer+=(xpos*2); // 2 in 16 bpp modes (need to take the mode into account)
193 // doom switches the resolution from 320 to 160 to double the display width
194 // this is not yet supported
199 uint8 d0=jaguar_byte_read(ptr+0);
200 uint8 d1=jaguar_byte_read(ptr+1);
201 *current_line_buffer++=d0;
202 *current_line_buffer++=d1;
203 *current_line_buffer++=d0;
204 *current_line_buffer++=d1;
210 if (op_bitmap_bit_depth[bitdepth]==1)
214 #include "include/fbmpop1.h"
218 #include "include/fbmpop1p.h"
222 if (op_bitmap_bit_depth[bitdepth]==2)
226 #include "include/fbmpop2.h"
230 #include "include/fbmpop2p.h"
234 if (op_bitmap_bit_depth[bitdepth]==4)
238 #include "include/fbmpop4.h"
242 #include "include/fbmpop4p.h"
246 if (op_bitmap_bit_depth[bitdepth]==8)
250 #include "include/fbmpop8.h"
254 #include "include/fbmpop8p.h"
258 if (op_bitmap_bit_depth[bitdepth]==16)
262 #include "include/fbmpop16.h"
266 #include "include/fbmpop16p.h"
270 if (op_bitmap_bit_depth[bitdepth]==24)
274 #include "include/fbmpop24.h"
278 #include "include/fbmpop24p.h"
282 //////////////////////////////////////////////////////////////////////////////
284 //////////////////////////////////////////////////////////////////////////////
288 //////////////////////////////////////////////////////////////////////////////
289 void op_process_scaled_bitmap(int16 *backbuffer, int scanline, uint64 p0, uint64 p1, uint64 p2, int render)
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 uint16 dwidth=((p1>>18)&0x3ff)*4;
295 uint16 height=(p0>>14)&0x3ff;
296 uint32 link=((p0>>24)&0x7ffff)<<3;
297 uint32 ptr=((p0>>43)&0x1fffff)<<3;
298 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];
309 uint32 vscale_fixed3p5=((p2>>8)&0xff);
310 uint32 hscale_fixed3p5=(p2&0xff);
311 vscale=((float)vscale_fixed3p5)/32;
312 hscale=((float)hscale_fixed3p5)/32;
316 if (jaguar_mainRom_crc32==0x5a5b9c68) // atari karts
326 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",
329 (int)(iwidth*hscale),
330 (int)(height*vscale),
332 op_bitmap_bit_depth[bitdepth],pitch,xpos,ypos,ptr,(flags&FLAGS_READMODIFY)?"yes":"no");
334 if (jaguar_mainRom_crc32==0x2f032271)
339 if ((render==0)||(op_pointer==0)||(height<0)||(dwidth<0)||(ptr==0)||(pitch==0))
344 if (op_bitmap_bit_depth[bitdepth]==8)
349 if (op_bitmap_bit_depth[bitdepth]==4)
354 if (op_bitmap_bit_depth[bitdepth]==2)
359 if (op_bitmap_bit_depth[bitdepth]==1)
365 uint16 scaled_width=iwidth*hscale;
366 uint16 scaled_height=height*vscale;
368 if (op_bitmap_bit_depth[bitdepth]==4) // why ?
371 if (op_bitmap_bit_depth[bitdepth]==2) // why ?
374 if (op_bitmap_bit_depth[bitdepth]==1) // why ?
377 // seek to the good bitmap scanline
378 // not sure for palettized modes
379 if (op_bitmap_bit_depth[bitdepth]>8)
380 ptr+=((dwidth*op_bitmap_bit_size[bitdepth])>>16)*((uint32)((scanline-ypos)/vscale));
382 ptr+=dwidth*((uint32)((scanline-ypos)/vscale));
385 if ((scanline<ypos)||(scanline>(ypos+scaled_height))||((xpos+scaled_width)<0)||(xpos>=scanline_width))
392 ptr+=(pitch*op_bitmap_bit_size[bitdepth]*((uint32)((-xpos)/hscale)))>>16;
399 if (flags&FLAGS_HFLIP)
401 if ((xpos<0)||((xpos-scaled_width)>=scanline_width))
404 if ((xpos-scaled_width)<0)
409 if (((xpos+scaled_width)<0)||(xpos>=scanline_width))
412 if ((xpos+scaled_width)>scanline_width)
413 scaled_width=scanline_width-xpos;
416 current_line_buffer+=(xpos*2);
418 int32 hscale_fixed=(int32)(65536.0f/hscale);
421 if (op_bitmap_bit_depth[bitdepth]==1)
425 #include "include/zbmpop1.h"
429 #include "include/zbmpop1p.h"
433 if (op_bitmap_bit_depth[bitdepth]==2)
437 #include "include/zbmpop2.h"
441 #include "include/zbmpop2p.h"
445 if (op_bitmap_bit_depth[bitdepth]==4)
449 #include "include/zbmpop4.h"
453 #include "include/zbmpop4p.h"
457 if (op_bitmap_bit_depth[bitdepth]==8)
461 #include "include/zbmpop8.h"
465 #include "include/zbmpop8p.h"
469 if (op_bitmap_bit_depth[bitdepth]==16)
473 #include "include/zbmpop16.h"
477 #include "include/zbmpop16p.h"
481 fprintf(log_get(),"(unimplemented) %i bpp scaled bitmap\n",op_bitmap_bit_depth[bitdepth]);
483 //////////////////////////////////////////////////////////////////////////////
485 //////////////////////////////////////////////////////////////////////////////
489 //////////////////////////////////////////////////////////////////////////////
490 uint64 op_load_phrase(uint32 offset)
492 offset &= (~0x07); // 8 byte alignment
494 uint64 data = jaguar_byte_read(offset++);
496 data |= jaguar_byte_read(offset++);
498 data |= jaguar_byte_read(offset++);
500 data |= jaguar_byte_read(offset++);
502 data |= jaguar_byte_read(offset++);
504 data |= jaguar_byte_read(offset++);
506 data |= jaguar_byte_read(offset++);
508 data |= jaguar_byte_read(offset++);
512 //////////////////////////////////////////////////////////////////////////////
514 //////////////////////////////////////////////////////////////////////////////
518 //////////////////////////////////////////////////////////////////////////////
519 void op_process_list(int16 * backbuffer, int scanline, int render)
525 if (scanline < tom_get_vdb())
528 if (scanline >= 525)//tom_getVideoModeHeight()+tom_get_vdb())
531 op_pointer = op_get_list_pointer();
533 objectp_stop_reading_list = 0;
536 // if (op_pointer) fprintf(log_get()," new op list at 0x%.8x scanline %i\n",op_pointer,scanline);
539 if (objectp_stop_reading_list)
542 p0 = op_load_phrase(op_pointer);
546 // fprintf(log_get(),"0x%.8x type %i\n",op_pointer,((uint8)p0&0x07));
547 switch ((uint8)p0&0x07)
549 case OBJECT_TYPE_BITMAP:
551 uint64 p1 = op_load_phrase(op_pointer);
553 op_process_bitmap(backbuffer, scanline, p0, p1, render);
556 case OBJECT_TYPE_SCALE:
558 uint64 p1 = op_load_phrase(op_pointer);
560 uint64 p2 = op_load_phrase(op_pointer);
562 op_process_scaled_bitmap(backbuffer, scanline, p0, p1, p2, render);
565 case OBJECT_TYPE_GPU:
567 uint64 data = p0 >> 3;
568 op_set_current_object(p0);
569 gpu_set_irq_line(3, 1);
572 case OBJECT_TYPE_BRANCH:
574 uint16 vcnt = (p0>>3) & 0x7FF;
575 uint8 cc = (p0>>14) & 0x03;
576 uint32 link = ((p0>>24) & 0x1FFFFF) << 3;
578 // if ((vcnt!=507)&&(vcnt!=25))
579 // fprintf(log_get(),"\t%i%s%i link=0x%.8x\n",scanline,condition_to_str[cc],vcnt>>1,link);
582 case CONDITION_EQUAL:
583 if ((vcnt != 0x7FF) && (vcnt & 0x01))
585 if (((2*tom_get_scanline()) == vcnt) || (vcnt == 0x7FF))
588 case CONDITION_LESS_THAN:
589 if ((2*tom_get_scanline()) < vcnt)
592 case CONDITION_GREATER_THAN:
593 if ((2*tom_get_scanline()) > vcnt)
596 case CONDITION_OP_FLAG_SET:
597 if (op_get_status_register() & 0x01)
600 case CONDITION_SECOND_HALF_LINE:
601 fprintf(log_get(), "op: unexpected CONDITION_SECOND_HALF_LINE in BRANCH object\nop: shuting down\n");
606 fprintf(log_get(),"op: unimplemented branch condition %i\n", cc);
610 case OBJECT_TYPE_STOP:
613 op_set_status_register(((p0>>3) & 0xFFFFFFFF));
617 tom_set_pending_object_int();
618 if ((tom_irq_enabled(2)) && (jaguar_interrupt_handler_is_valid(64)))
620 // s68000interrupt(7,64);
621 // s68000flushInterrupts();
622 m68k_set_irq(7); // Cause an NMI to occur...
631 fprintf(log_get(),"op: unknown object type %i\n", ((uint8)p0 & 0x07));
637 //////////////////////////////////////////////////////////////////////////////
639 //////////////////////////////////////////////////////////////////////////////
643 //////////////////////////////////////////////////////////////////////////////
646 memory_malloc_secure((void **)&op_blend_y, 0x10000, "Jaguar Object processor Y blend lookup table");
647 memory_malloc_secure((void **)&op_blend_cc, 0x10000, "Jaguar Object processor C blend lookup table");
649 for(int i=0; i<256*256; i++)
651 int y = (i >> 8) & 0xFF;
652 int dy = (int8)(i & 0xFF);
661 for(int i=0; i<256*256; i++)
663 int cl = (i >> 8) & 0xFF;
664 int dcl = (int8)(i & 0xFF);
674 //////////////////////////////////////////////////////////////////////////////
676 //////////////////////////////////////////////////////////////////////////////
680 //////////////////////////////////////////////////////////////////////////////
683 memset(objectp_ram, 0x00, 0x18);
686 //////////////////////////////////////////////////////////////////////////////
688 //////////////////////////////////////////////////////////////////////////////
692 //////////////////////////////////////////////////////////////////////////////
696 //////////////////////////////////////////////////////////////////////////////
698 //////////////////////////////////////////////////////////////////////////////
702 //////////////////////////////////////////////////////////////////////////////
703 void op_byte_write(uint32 offset, uint8 data)
706 objectp_ram[offset] = data;
708 //////////////////////////////////////////////////////////////////////////////
710 //////////////////////////////////////////////////////////////////////////////
714 //////////////////////////////////////////////////////////////////////////////
715 void op_word_write(uint32 offset, uint16 data)
718 objectp_ram[offset] = (data >> 8) & 0xFF;
719 objectp_ram[offset+1] = data & 0xFF;
722 //////////////////////////////////////////////////////////////////////////////
724 //////////////////////////////////////////////////////////////////////////////
728 //////////////////////////////////////////////////////////////////////////////
729 uint8 op_byte_read(uint32 offset)
732 return objectp_ram[offset];
734 //////////////////////////////////////////////////////////////////////////////
736 //////////////////////////////////////////////////////////////////////////////
740 //////////////////////////////////////////////////////////////////////////////
741 uint16 op_word_read(uint32 offset)
743 return (objectp_ram[offset & 0x3F] << 8) | objectp_ram[(offset+1) & 0x3F];
745 //////////////////////////////////////////////////////////////////////////////
747 //////////////////////////////////////////////////////////////////////////////
751 //////////////////////////////////////////////////////////////////////////////
752 uint32 op_get_list_pointer(void)
754 uint32 ptr = objectp_ram[0x22];
756 ptr |= objectp_ram[0x23];
758 ptr |= objectp_ram[0x20];
760 ptr |= objectp_ram[0x21];
764 // return (objectp_ram[0x20] << 24) | (objectp_ram[0x21] << 16) | (objectp_ram[0x22] << 8) | objectp_ram[0x23];
766 //////////////////////////////////////////////////////////////////////////////
768 //////////////////////////////////////////////////////////////////////////////
772 //////////////////////////////////////////////////////////////////////////////
773 uint32 op_get_status_register(void)
775 uint32 ptr = objectp_ram[0x26];
777 ptr |= objectp_ram[0x27];
779 ptr |= objectp_ram[0x28];
781 ptr |= objectp_ram[0x29];
785 //////////////////////////////////////////////////////////////////////////////
787 //////////////////////////////////////////////////////////////////////////////
791 //////////////////////////////////////////////////////////////////////////////
792 void op_set_status_register(uint32 data)
794 objectp_ram[0x26] = (data & 0xFF000000) >> 24;
795 objectp_ram[0x27] = (data & 0x00FF0000) >> 16;
796 objectp_ram[0x28] = (data & 0x0000FF00) >> 8;
797 objectp_ram[0x29] |= (data & 0xFE);
799 //////////////////////////////////////////////////////////////////////////////
801 //////////////////////////////////////////////////////////////////////////////
805 //////////////////////////////////////////////////////////////////////////////
806 void op_set_current_object(uint64 object)
808 // less significant 32 bits first
809 objectp_ram[0x13] = object&0xff; object>>=8;
810 objectp_ram[0x12] = object&0xff; object>>=8;
811 objectp_ram[0x11] = object&0xff; object>>=8;
812 objectp_ram[0x10] = object&0xff; object>>=8;
814 objectp_ram[0x17] = object&0xff; object>>=8;
815 objectp_ram[0x16] = object&0xff; object>>=8;
816 objectp_ram[0x15] = object&0xff; object>>=8;
817 objectp_ram[0x14] = object&0xff;