1 #include "rockmacros.h"
9 #include "palette-presets.h"
17 struct scan scan IBSS_ATTR
;
20 #define WND (scan.wnd)
23 #define BUF (scan.buf)
25 #define BUF (scan.buf[scanline_ind])
28 #define PRI (scan.pri)
30 #define PAL (scan.pal)
32 #define VS (scan.vs) /* vissprites */
35 #define L (scan.l) /* line */
36 #define X (scan.x) /* screen position */
38 #define S (scan.s) /* tilemap position */
40 #define U (scan.u) /* position within tile */
47 byte patpix
[4096][8][8]
48 #if defined(CPU_COLDFIRE)
49 __attribute__ ((aligned(16))) /* to profit from burst mode */
56 static int scanline_ind
=0;
59 static int dmg_pal
[4][4];
63 #ifndef ASM_UPDATEPATPIX
64 static void updatepatpix(void) ICODE_ATTR
;
65 static void updatepatpix(void)
68 #if ((CONFIG_CPU != SH7034) && !defined(CPU_COLDFIRE))
71 byte
*vram
= lcd
.vbank
[0];
73 if (!anydirty
) return;
74 for (i
= 0; i
< 1024; i
++)
76 if (i
== 384) i
= 512;
78 if (!patdirty
[i
]) continue;
80 for (j
= 0; j
< 8; j
++)
82 #if CONFIG_CPU == SH7034
100 "mov.b r0,@(6,%1) \n"
106 "mov.b r0,@(2,%0) \n"
107 "mov.b r0,@(5,%1) \n"
113 "mov.b r0,@(3,%0) \n"
114 "mov.b r0,@(4,%1) \n"
120 "mov.b r0,@(4,%0) \n"
121 "mov.b r0,@(3,%1) \n"
127 "mov.b r0,@(5,%0) \n"
128 "mov.b r0,@(2,%1) \n"
134 "mov.b r0,@(6,%0) \n"
135 "mov.b r0,@(1,%1) \n"
141 "mov.b r0,@(7,%0) \n"
145 /* %0 */ "r"(patpix
[i
+1024][j
]),
146 /* %1 */ "r"(patpix
[i
][j
]),
147 /* %2 */ "r"(&vram
[(i
<<4)|(j
<<1)])
151 #elif defined(CPU_COLDFIRE)
153 "move.b (%2),%%d2 \n"
154 "move.b (1,%2),%%d1 \n"
159 "addx.l %%d0,%%d0 \n"
161 "addx.l %%d0,%%d0 \n"
162 "move.b %%d0,-(%1) \n"
165 "addx.l %%d0,%%d0 \n"
167 "addx.l %%d0,%%d0 \n"
168 "move.b %%d0,-(%1) \n"
171 "addx.l %%d0,%%d0 \n"
173 "addx.l %%d0,%%d0 \n"
174 "move.b %%d0,-(%1) \n"
177 "addx.l %%d0,%%d0 \n"
179 "addx.l %%d0,%%d0 \n"
180 "move.l %%d0,(%0) \n"
181 "move.b %%d0,-(%1) \n"
184 "addx.l %%d0,%%d0 \n"
186 "addx.l %%d0,%%d0 \n"
187 "move.b %%d0,-(%1) \n"
190 "addx.l %%d0,%%d0 \n"
192 "addx.l %%d0,%%d0 \n"
193 "move.b %%d0,-(%1) \n"
196 "addx.l %%d0,%%d0 \n"
198 "addx.l %%d0,%%d0 \n"
199 "move.b %%d0,-(%1) \n"
202 "addx.l %%d0,%%d0 \n"
204 "addx.l %%d0,%%d0 \n"
205 "move.l %%d0,(4,%0) \n"
206 "move.b %%d0,-(%1) \n"
209 /* %0 */ "a"(patpix
[i
+1024][j
]),
210 /* %1 */ "a"(patpix
[i
][j
]),
211 /* %2 */ "a"(&vram
[(i
<<4)|(j
<<1)])
216 a
= ((i
<<4) | (j
<<1));
217 for (k
= 0; k
< 8; k
++)
219 c
= vram
[a
] & (1<<k
) ? 1 : 0;
220 c
|= vram
[a
+1] & (1<<k
) ? 2 : 0;
221 patpix
[i
+1024][j
][k
] = c
;
223 for (k
= 0; k
< 8; k
++)
225 patpix
[i
+1024][j
][7-k
];
228 #if CONFIG_CPU == SH7034
231 "mov.l @(4,%0),r1 \n"
232 "mov.l r0,@(56,%1) \n"
233 "mov.l r1,@(60,%1) \n"
234 "mov.l @(8,%0),r0 \n"
235 "mov.l @(12,%0),r1 \n"
236 "mov.l r0,@(48,%1) \n"
237 "mov.l r1,@(52,%1) \n"
238 "mov.l @(16,%0),r0 \n"
239 "mov.l @(20,%0),r1 \n"
240 "mov.l r0,@(40,%1) \n"
241 "mov.l r1,@(44,%1) \n"
242 "mov.l @(24,%0),r0 \n"
243 "mov.l @(28,%0),r1 \n"
244 "mov.l r0,@(32,%1) \n"
245 "mov.l r1,@(36,%1) \n"
246 "mov.l @(32,%0),r0 \n"
247 "mov.l @(36,%0),r1 \n"
248 "mov.l r0,@(24,%1) \n"
249 "mov.l r1,@(28,%1) \n"
250 "mov.l @(40,%0),r0 \n"
251 "mov.l @(44,%0),r1 \n"
252 "mov.l r0,@(16,%1) \n"
253 "mov.l r1,@(20,%1) \n"
254 "mov.l @(48,%0),r0 \n"
255 "mov.l @(52,%0),r1 \n"
256 "mov.l r0,@(8,%1) \n"
257 "mov.l r1,@(12,%1) \n"
258 "mov.l @(56,%0),r0 \n"
259 "mov.l @(60,%0),r1 \n"
261 "mov.l r1,@(4,%1) \n"
267 "mov.l @(4,%0),r1 \n"
268 "mov.l r0,@(56,%1) \n"
269 "mov.l r1,@(60,%1) \n"
270 "mov.l @(8,%0),r0 \n"
271 "mov.l @(12,%0),r1 \n"
272 "mov.l r0,@(48,%1) \n"
273 "mov.l r1,@(52,%1) \n"
274 "mov.l @(16,%0),r0 \n"
275 "mov.l @(20,%0),r1 \n"
276 "mov.l r0,@(40,%1) \n"
277 "mov.l r1,@(44,%1) \n"
278 "mov.l @(24,%0),r0 \n"
279 "mov.l @(28,%0),r1 \n"
280 "mov.l r0,@(32,%1) \n"
281 "mov.l r1,@(36,%1) \n"
282 "mov.l @(32,%0),r0 \n"
283 "mov.l @(36,%0),r1 \n"
284 "mov.l r0,@(24,%1) \n"
285 "mov.l r1,@(28,%1) \n"
286 "mov.l @(40,%0),r0 \n"
287 "mov.l @(44,%0),r1 \n"
288 "mov.l r0,@(16,%1) \n"
289 "mov.l r1,@(20,%1) \n"
290 "mov.l @(48,%0),r0 \n"
291 "mov.l @(52,%0),r1 \n"
292 "mov.l r0,@(8,%1) \n"
293 "mov.l r1,@(12,%1) \n"
294 "mov.l @(56,%0),r0 \n"
295 "mov.l @(60,%0),r1 \n"
297 "mov.l r1,@(4,%1) \n"
300 /* %0 */ "r"(patpix
[i
][0]),
301 /* %1 */ "r"(patpix
[i
+2048][0]),
302 /* %2 */ "r"(1024*64)
306 #elif defined(CPU_COLDFIRE)
308 "movem.l (%0),%%d0-%%d3 \n"
309 "move.l %%d0,%%d4 \n"
310 "move.l %%d1,%%d5 \n"
311 "movem.l %%d2-%%d5,(48,%1) \n"
312 "movem.l (16,%0),%%d0-%%d3 \n"
313 "move.l %%d0,%%d4 \n"
314 "move.l %%d1,%%d5 \n"
315 "movem.l %%d2-%%d5,(32,%1) \n"
316 "movem.l (32,%0),%%d0-%%d3 \n"
317 "move.l %%d0,%%d4 \n"
318 "move.l %%d1,%%d5 \n"
319 "movem.l %%d2-%%d5,(16,%1) \n"
320 "movem.l (48,%0),%%d0-%%d3 \n"
321 "move.l %%d0,%%d4 \n"
322 "move.l %%d1,%%d5 \n"
323 "movem.l %%d2-%%d5,(%1) \n"
329 "movem.l (%0),%%d0-%%d3 \n"
330 "move.l %%d0,%%d4 \n"
331 "move.l %%d1,%%d5 \n"
332 "movem.l %%d2-%%d5,(48,%1) \n"
333 "movem.l (16,%0),%%d0-%%d3 \n"
334 "move.l %%d0,%%d4 \n"
335 "move.l %%d1,%%d5 \n"
336 "movem.l %%d2-%%d5,(32,%1) \n"
337 "movem.l (32,%0),%%d0-%%d3 \n"
338 "move.l %%d0,%%d4 \n"
339 "move.l %%d1,%%d5 \n"
340 "movem.l %%d2-%%d5,(16,%1) \n"
341 "movem.l (48,%0),%%d0-%%d3 \n"
342 "move.l %%d0,%%d4 \n"
343 "move.l %%d1,%%d5 \n"
344 "movem.l %%d2-%%d5,(%1) \n"
347 /* %0 */ "a"(patpix
[i
][0]),
348 /* %1 */ "a"(patpix
[i
+2048][0]),
349 /* %2 */ "i"(1024*64)
351 "d0", "d1", "d2", "d3", "d4", "d5"
354 for (j
= 0; j
< 8; j
++)
356 for (k
= 0; k
< 8; k
++)
358 patpix
[i
+2048][j
][k
] =
360 patpix
[i
+3072][j
][k
] =
361 patpix
[i
+1024][7-j
][k
];
368 #endif /* ASM_UPDATEPATPIX */
372 static void tilebuf(void) ICODE_ATTR
;
373 static void tilebuf(void)
377 byte
*tilemap
, *attrmap
;
380 static int wraptable
[64] =
382 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
383 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,-32
386 base
= ((R_LCDC
&0x08)?0x1C00:0x1800) + (T
<<5) + S
;
387 tilemap
= lcd
.vbank
[0] + base
;
388 attrmap
= lcd
.vbank
[1] + base
;
390 wrap
= wraptable
+ S
;
391 cnt
= ((WX
+ 7) >> 3) + 1;
395 for (i
= cnt
; i
> 0; i
--)
397 *(tilebuf
++) = *tilemap
398 | (((int)*attrmap
& 0x08) << 6)
399 | (((int)*attrmap
& 0x60) << 5);
400 *(tilebuf
++) = (((int)*attrmap
& 0x07) << 2);
401 attrmap
+= *wrap
+ 1;
402 tilemap
+= *(wrap
++) + 1;
405 for (i
= cnt
; i
> 0; i
--)
407 *(tilebuf
++) = (256 + ((n8
)*tilemap
))
408 | (((int)*attrmap
& 0x08) << 6)
409 | (((int)*attrmap
& 0x60) << 5);
410 *(tilebuf
++) = (((int)*attrmap
& 0x07) << 2);
411 attrmap
+= *wrap
+ 1;
412 tilemap
+= *(wrap
++) + 1;
418 for (i
= cnt
; i
> 0; i
--)
420 *(tilebuf
++) = *(tilemap
++);
421 tilemap
+= *(wrap
++);
424 for (i
= cnt
; i
> 0; i
--)
426 *(tilebuf
++) = (256 + ((n8
)*(tilemap
++)));
427 tilemap
+= *(wrap
++);
431 if (WX
>= 160) return;
433 base
= ((R_LCDC
&0x40)?0x1C00:0x1800) + (WT
<<5);
434 tilemap
= lcd
.vbank
[0] + base
;
435 attrmap
= lcd
.vbank
[1] + base
;
437 cnt
= ((160 - WX
) >> 3) + 1;
442 for (i
= cnt
; i
> 0; i
--)
444 *(tilebuf
++) = *(tilemap
++)
445 | (((int)*attrmap
& 0x08) << 6)
446 | (((int)*attrmap
& 0x60) << 5);
447 *(tilebuf
++) = (((int)*(attrmap
++)&7) << 2);
450 for (i
= cnt
; i
> 0; i
--)
452 *(tilebuf
++) = (256 + ((n8
)*(tilemap
++)))
453 | (((int)*attrmap
& 0x08) << 6)
454 | (((int)*attrmap
& 0x60) << 5);
455 *(tilebuf
++) = (((int)*(attrmap
++)&7) << 2);
462 for (i
= cnt
; i
> 0; i
--)
463 *(tilebuf
++) = *(tilemap
++);
465 for (i
= cnt
; i
> 0; i
--)
466 *(tilebuf
++) = (256 + ((n8
)*(tilemap
++)));
472 * WX = WND start (if 0, no need to do anything) -> WY
473 * U = start...something...thingy... 7 at most
475 static void bg_scan(void) ICODE_ATTR
;
476 static void bg_scan(void)
487 src
= patpix
[*(tile
++)][V
] + U
;
488 memcpy(dest
, src
, 8-U
);
491 if (cnt
<= 0) return;
494 #if defined(CPU_COLDFIRE)
496 "move.l (%1)+,(%0)+ \n"
497 "move.l (%1)+,(%0)+ \n"
501 /* %1 */ "a" (patpix
[*(tile
++)][V
])
505 src
= patpix
[*(tile
++)][V
];
511 src
= patpix
[*tile
][V
];
513 *(dest
++) = *(src
++);
516 static void wnd_scan(void) ICODE_ATTR
;
517 static void wnd_scan(void)
523 if (WX
>= 160) return;
530 #if defined(CPU_COLDFIRE)
532 "move.l (%1)+,(%0)+ \n"
533 "move.l (%1)+,(%0)+ \n"
537 /* %1 */ "a" (patpix
[*(tile
++)][WV
])
541 src
= patpix
[*(tile
++)][WV
];
547 src
= patpix
[*tile
][WV
];
549 *(dest
++) = *(src
++);
552 static void blendcpy(byte
*dest
, byte
*src
, byte b
, int cnt
)
554 while (cnt
--) *(dest
++) = *(src
++) | b
;
557 static int priused(void *attr
)
560 return (int)((a
[0]|a
[1]|a
[2]|a
[3]|a
[4]|a
[5]|a
[6]|a
[7])&0x80808080);
563 static void bg_scan_pri(void) ICODE_ATTR
;
564 static void bg_scan_pri(void)
573 src
= lcd
.vbank
[1] + ((R_LCDC
&0x08)?0x1C00:0x1800) + (T
<<5);
577 memset(dest
, 0, cnt
);
581 memset(dest
, src
[i
++&31]&128, 8-U
);
584 if (cnt
<= 0) return;
587 memset(dest
, src
[i
++&31]&128, 8);
591 memset(dest
, src
[i
&31]&128, cnt
);
594 static void wnd_scan_pri(void) ICODE_ATTR
;
595 static void wnd_scan_pri(void)
600 if (WX
>= 160) return;
604 src
= lcd
.vbank
[1] + ((R_LCDC
&0x40)?0x1C00:0x1800) + (WT
<<5);
608 memset(dest
, 0, cnt
);
614 memset(dest
, src
[i
++]&128, 8);
618 memset(dest
, src
[i
]&128, cnt
);
621 static void bg_scan_color(void)
632 src
= patpix
[*(tile
++)][V
] + U
;
633 blendcpy(dest
, src
, *(tile
++), 8-U
);
636 if (cnt
<= 0) return;
639 src
= patpix
[*(tile
++)][V
];
640 #if defined(CPU_COLDFIRE)
642 "move.l (%2)+,%%d1 \n"
644 "move.b %%d1,%%d2 \n"
646 "move.b (%1)+,%%d0 \n"
648 "move.b %%d0,(%0)+ \n"
650 "move.b (%1)+,%%d0 \n"
652 "move.b %%d0,(%0)+ \n"
654 "move.b (%1)+,%%d0 \n"
656 "move.b %%d0,(%0)+ \n"
658 "move.b (%1)+,%%d0 \n"
660 "move.b %%d0,(%0)+ \n"
662 "move.b (%1)+,%%d0 \n"
664 "move.b %%d0,(%0)+ \n"
666 "move.b (%1)+,%%d0 \n"
668 "move.b %%d0,(%0)+ \n"
670 "move.b (%1)+,%%d0 \n"
672 "move.b %%d0,(%0)+ \n"
674 "move.b (%1)+,%%d0 \n"
676 "move.b %%d0,(%0)+ \n"
686 blendcpy(dest
, src
, *(tile
++), 8);
691 src
= patpix
[*(tile
++)][V
];
692 blendcpy(dest
, src
, *(tile
++), cnt
);
695 static void wnd_scan_color(void)
701 if (WX
>= 160) return;
708 src
= patpix
[*(tile
++)][WV
];
709 blendcpy(dest
, src
, *(tile
++), 8);
713 src
= patpix
[*(tile
++)][WV
];
714 blendcpy(dest
, src
, *(tile
++), cnt
);
717 static void spr_enum(void) ICODE_ATTR
;
718 static void spr_enum(void)
726 if (!(R_LCDC
& 0x02)) return;
730 for (i
= 40; i
; i
--, o
++)
732 if (L
>= o
->y
|| L
+ 16 < o
->y
)
734 if (L
+ 8 >= o
->y
&& !(R_LCDC
& 0x04))
736 VS
[NS
].x
= (int)o
->x
- 8;
737 v
= L
- (int)o
->y
+ 16;
740 pat
= o
->pat
| (((int)o
->flags
& 0x60) << 5)
741 | (((int)o
->flags
& 0x08) << 6);
742 VS
[NS
].pal
= 32 + ((o
->flags
& 0x07) << 2);
746 pat
= o
->pat
| (((int)o
->flags
& 0x60) << 5);
747 VS
[NS
].pal
= 32 + ((o
->flags
& 0x10) >> 2);
749 VS
[NS
].pri
= (o
->flags
& 0x80) >> 7;
758 if (o
->flags
& 0x40) pat
^= 1;
760 VS
[NS
].buf
= patpix
[pat
][v
];
761 if (++NS
== 10) break;
764 for (i
= 0; i
< NS
; i
++)
766 for (j
= i
+ 1; j
< NS
; j
++)
768 if (VS
[i
].x
> VS
[j
].x
)
778 static void spr_scan(void) ICODE_ATTR
;
779 static void spr_scan(void)
782 byte pal
, b
, ns
= NS
;
783 byte
*src
, *dest
, *bg
, *pri
;
784 struct vissprite
*vs
;
785 static byte bgdup
[256];
789 memcpy(bgdup
, BUF
, 256);
792 for (; ns
; ns
--, vs
--)
795 if (x
> 159) continue;
796 if (x
< -7) continue;
807 if (x
> 152) i
= 160 - x
;
813 bg
= bgdup
+ (dest
- BUF
);
817 if (b
&& !(bg
[i
]&3)) dest
[i
] = pal
|b
;
822 bg
= bgdup
+ (dest
- BUF
);
823 pri
= PRI
+ (dest
- BUF
);
827 if (b
&& (!pri
[i
] || !(bg
[i
]&3)))
831 else while (i
--) if (src
[i
]) dest
[i
] = pal
|src
[i
];
835 /* Scaling defines */
836 #define DX ((LCD_WIDTH<<16) / 160)
837 #define DXI ((160<<16) / LCD_WIDTH)
838 #define DY ((LCD_HEIGHT<<16) / 144)
839 #define DYI ((144<<16) / LCD_HEIGHT)
841 #define DXR ((LCD_WIDTH<<16) / 144)
842 #define DXIR ((144<<16) / LCD_WIDTH)
843 #define DYR ((LCD_HEIGHT<<16) / 160)
844 #define DYIR ((160<<16) / LCD_HEIGHT)
849 #if (LCD_WIDTH>=160) && (LCD_HEIGHT>=144)
850 #define S1 ((LCD_HEIGHT-144)/2)*LCD_WIDTH + ((LCD_WIDTH-160)/2)
852 #define S1R ((LCD_HEIGHT-160)/2)*LCD_WIDTH + ((LCD_WIDTH-144)/2)+144
853 #define S2R (LCD_WIDTH-1)
855 #elif (LCD_WIDTH>=160) && (LCD_HEIGHT<=144)
858 #define S1R LCD_WIDTH-1
859 #define S2R LCD_WIDTH-1
861 #elif (LCD_WIDTH<=160) && (LCD_HEIGHT>=144)
862 #define S1 ((LCD_HEIGHT-144)/2)*LCD_WIDTH
863 #define S2 ((LCD_HEIGHT-144)/2)*LCD_WIDTH
864 #define S1R LCD_WIDTH-1
865 #define S2R LCD_WIDTH-1
870 #define S1R LCD_WIDTH-1
871 #define S2R LCD_WIDTH-1
874 #if (LCD_WIDTH>LCD_HEIGHT)
875 #define S3 ((LCD_WIDTH-((160*DY)>>16))/2)
876 #define S3R LCD_WIDTH-1
878 #define S3 ((LCD_HEIGHT-((144*DX)>>16))/2)*LCD_WIDTH
879 #define S3R ((LCD_HEIGHT-((160*DXR)>>16))/2)*LCD_WIDTH+LCD_WIDTH-1
882 vdest
=rb
->lcd_framebuffer
;
883 #ifdef HAVE_LCD_COLOR
888 if(options
.scaling
== 0)
890 else if (options
.scaling
== 1)
897 if(options
.scaling
== 0)
899 else if (options
.scaling
== 1)
908 #ifdef HAVE_LCD_COLOR
909 int SCALEWL IDATA_ATTR
=1<<16;
910 int SCALEWS IDATA_ATTR
=1<<16;
911 int SCALEHL IDATA_ATTR
=1<<16;
912 int SCALEHS IDATA_ATTR
=1<<16;
913 int swidth IDATA_ATTR
=160;
914 int sremain IDATA_ATTR
=LCD_WIDTH
-160;
917 void setvidmode(void)
919 #ifdef HAVE_LCD_COLOR
920 switch(options
.scaling
)
938 case 1: /* Maintain Ratio */
980 swidth
=(160*SCALEWL
)>>16;
983 sremain
=-(((160*SCALEWL
)>>16)*LCD_WIDTH
+1);
985 sremain
=LCD_WIDTH
-swidth
;
989 void lcd_refreshline(void)
991 #ifdef HAVE_LCD_COLOR
995 if (!(R_LCDC
& 0x80))
996 return; /* should not happen... */
998 #if (LCD_HEIGHT <= 128) && !defined(HAVE_LCD_COLOR)
999 if ( (fb
.mode
==0&&(R_LY
>= 128)) ||
1000 (fb
.mode
==1&&(R_LY
< 16)) ||
1001 (fb
.mode
==2&&(R_LY
<8||R_LY
>=136)) ||
1002 (fb
.mode
==3&&((R_LY
%9)==8))
1004 #if LCD_HEIGHT == 64
1005 || (R_LY
& 1) /* calculate only even lines */
1015 Y
= (R_SCY
+ L
) & 0xff;
1022 if (WY
>L
|| WY
<0 || WY
>143 || WX
<-7 || WX
>159 || !(R_LCDC
&0x20))
1048 #if !defined(HAVE_LCD_COLOR)
1050 if (scanline_ind
== 7)
1051 #elif LCD_DEPTH == 2
1052 if (scanline_ind
== 3)
1058 vid_update(L
-((int)(L
/9)));
1061 /* Universal Scaling pulled from PrBoom and modified for rockboy */
1063 static int hpt IDATA_ATTR
=0x8000;
1065 while((hpt
>>16)<L
+1)
1068 register unsigned int srcpt
=0x8000;
1069 register unsigned int wcount
=swidth
;
1070 register unsigned int remain
=sremain
;
1073 *vdest
= PAL
[BUF
[srcpt
>>16]];
1086 if(options
.showstats
)
1088 snprintf(frameout
,sizeof(frameout
),"FPS: %d Frameskip: %d ",options
.fps
, options
.frameskip
);
1089 rb
->lcd_putsxy(0,LCD_HEIGHT
-10,frameout
);
1099 scanline_ind
= (scanline_ind
+1) % 8;
1100 #elif LCD_DEPTH == 2
1101 scanline_ind
= (scanline_ind
+1) % 4;
1105 #ifdef HAVE_LCD_COLOR
1108 memcpy(dmg_pal
,palettes
[options
.pal
], sizeof(dmg_pal
));
1112 static void updatepalette(int i
)
1116 c
= (lcd
.pal
[i
<<1] | ((int)lcd
.pal
[(i
<<1)|1] << 8)) & 0x7FFF;
1117 r
= (c
& 0x001F) << 3;
1118 g
= (c
& 0x03E0) >> 2;
1119 b
= (c
& 0x7C00) >> 7;
1124 r
= (r
>> fb
.cc
[0].r
) << fb
.cc
[0].l
;
1125 g
= (g
>> fb
.cc
[1].r
) << fb
.cc
[1].l
;
1126 b
= (b
>> fb
.cc
[2].r
) << fb
.cc
[2].l
;
1128 #if LCD_PIXELFORMAT == RGB565
1130 #elif LCD_PIXELFORMAT == RGB565SWAPPED
1135 #endif /* HAVE_LCD_COLOR */
1137 void pal_write(int i
, byte b
)
1139 if (lcd
.pal
[i
] == b
) return;
1141 #ifdef HAVE_LCD_COLOR
1142 updatepalette(i
>>1);
1146 void pal_write_dmg(int i
, int mapnum
, byte d
)
1149 int *cmap
= dmg_pal
[mapnum
];
1154 for (j
= 0; j
< 8; j
+= 2)
1156 c
= cmap
[(d
>> j
) & 3];
1157 r
= (c
& 0xf8) >> 3;
1158 g
= (c
& 0xf800) >> 6;
1159 b
= (c
& 0xf80000) >> 9;
1161 /* FIXME - handle directly without faking cgb */
1162 pal_write(i
+j
, c
& 0xff);
1163 pal_write(i
+j
+1, c
>> 8);
1167 void vram_write(addr a
, byte b
)
1169 lcd
.vbank
[R_VBK
&1][a
] = b
;
1170 if (a
>= 0x1800) return;
1171 patdirty
[((R_VBK
&1)<<9)+(a
>>4)] = 1;
1175 void vram_dirty(void)
1178 memset(patdirty
, 1, sizeof patdirty
);
1181 void pal_dirty(void)
1183 #ifdef HAVE_LCD_COLOR
1189 pal_write_dmg(0, 0, R_BGP
);
1190 pal_write_dmg(8, 1, R_BGP
);
1191 pal_write_dmg(64, 2, R_OBP0
);
1192 pal_write_dmg(72, 3, R_OBP1
);
1194 #ifdef HAVE_LCD_COLOR
1195 for (i
= 0; i
< 64; i
++)
1200 void lcd_reset(void)
1202 memset(&lcd
, 0, sizeof lcd
);