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