OSDN Git Service

[VM][FM7][DISPLAY] Simplify logic of draw_screen().
[csp-qt/common_source_project-fm7.git] / source / src / vm / fm7 / vram.cpp
1 /*
2  * Common source code project -> FM-7 -> Display -> Vram access
3  * (C) 2015 K.Ohta <whatisthis.sowhat _at_ gmail.com>
4  * History:
5  *  Sep 27, 2015 : Split from display.cpp .
6  */
7
8 #include "vm.h"
9 #include "emu.h"
10 #include "fm7_display.h"
11 #if defined(_FM77L4)
12 #include "../hd46505.h"
13 #endif
14
15 extern config_t config;
16
17 namespace FM7 {
18
19 void DISPLAY::clear_display(int dmode, int w, int h)
20 {
21 #if defined(FIXED_FRAMEBUFFER_SIZE)
22         if((dmode != DISPLAY_MODE_8_400L) && (dmode != DISPLAY_MODE_1_400L)) {
23                 h = h * 2;
24         }
25 #endif
26         for(int yy = 0; yy < h; yy++) {
27                 scrntype_t *p;
28                 p = emu->get_screen_buffer(yy);
29                 if(p != NULL) {
30                         memset(p, 0x00, sizeof(scrntype_t) * w);
31                 }
32         }
33 }
34
35 void DISPLAY::draw_window(int dmode, int y, int begin, int bytes, bool window_inv, bool scan_line)
36 {
37         _render_command_data_t cmd;
38         bool use_cmd = false;
39         int xzoom = 1;
40         uint32_t _offset_base = 0x4000;
41         int planes;
42         int shift;
43         int width;
44         switch(dmode) {
45         case DISPLAY_MODE_8_200L:
46                 _offset_base = 0x4000;
47                 use_cmd = true;
48                 planes = 3;
49                 shift = 5;
50                 width = 80;
51                 break;
52 #if defined(_FM77AV_VARIANTS)
53         case DISPLAY_MODE_4096:
54                 _offset_base = 0x2000;
55                 xzoom = 2;
56                 planes = 12;
57                 shift = 5;
58                 width = 40;
59                 break;
60 #  if defined(_FM77AV40EX) || defined(_FM77AV40SX) || defined(_FM77AV40)
61         case DISPLAY_MODE_8_400L:
62                 _offset_base = 0x8000;
63                 use_cmd = true;
64                 planes = 3;
65                 shift = 5;
66                 width = 80;
67                 break;
68 #    if defined(_FM77AV40EX) || defined(_FM77AV40SX)
69         case DISPLAY_MODE_256k:
70                 _offset_base = 0x2000;
71                 xzoom = 2;
72                 planes = 20;
73                 shift = 5;
74                 width = 40;
75                 break;
76 #    endif
77 #  endif
78 #endif
79         default:
80                 return;
81                 break;
82         }
83         if(use_cmd) {
84                 memset(&cmd, 0x00, sizeof(_render_command_data_t));
85 #if defined(USE_GREEN_DISPLAY)
86                 if(use_green_monitor) {
87                         cmd.palette = dpalette_pixel_green;
88                 } else {
89                         cmd.palette = dpalette_pixel;
90                 }
91 #else
92                 cmd.palette = dpalette_pixel;
93 #endif                          
94                 if(!multimode_dispflags[0]) cmd.is_render[0] = true;
95                 if(!multimode_dispflags[1]) cmd.is_render[1] = true;
96                 if(!multimode_dispflags[2]) cmd.is_render[2] = true;
97                 cmd.bit_trans_table[0] = (_bit_trans_table_t*)(&(bit_trans_table_2[0][0])); // B
98                 cmd.bit_trans_table[1] = (_bit_trans_table_t*)(&(bit_trans_table_1[0][0])); // R
99                 cmd.bit_trans_table[2] = (_bit_trans_table_t*)(&(bit_trans_table_0[0][0])); // G
100                 for(int i = 0; i < 3; i++) {
101                         cmd.data[i] = gvram_shadow;
102                         cmd.baseaddress[i] = (i * _offset_base) + yoff_d;
103                         cmd.voffset[i] = y * width;
104                 }
105                 cmd.xzoom = xzoom;
106                 cmd.addrmask = _offset_base - 1;
107                 cmd.addrmask2 = _offset_base - 1;
108                 cmd.render_width = bytes;
109                 cmd.begin_pos = begin;
110                 cmd.shift = shift;
111         }
112         scrntype_t *p;
113         scrntype_t *pp;
114         if(dmode == DISPLAY_MODE_8_400L) {
115 #if defined(_FM77AV40EX) || defined(_FM77AV40SX) || defined(_FM77AV40)
116                 p = emu->get_screen_buffer(y);
117                 if(p == NULL) return;
118                 Render8Colors_Line(&cmd, &(p[cmd.begin_pos * 8]), NULL, false);
119 #endif
120         } else {
121 #if !defined(FIXED_FRAMEBUFFER_SIZE)
122                 p = emu->get_screen_buffer(y);
123                 pp = NULL;
124 #else
125                 p = emu->get_screen_buffer(y << 1);
126                 pp = emu->get_screen_buffer((y << 1) + 1);
127 #endif
128                 if(p == NULL) return;
129                 switch(dmode) {
130                 case DISPLAY_MODE_8_200L:
131                         {
132                                 if(pp != NULL) {
133                                         Render8Colors_Line(&cmd, &(p[cmd.begin_pos * 8]), &(pp[cmd.begin_pos * 8]), scan_line);
134                                 } else {
135                                         Render8Colors_Line(&cmd, &(p[cmd.begin_pos * 8]), NULL, false);
136                                 }
137                         }
138                         break;
139 #if defined(_FM77AV_VARIANTS)
140                 case DISPLAY_MODE_4096:
141                         {
142                                 uint32_t mask = 0x000;
143                                 if(!multimode_dispflags[0]) mask = 0x00f;
144                                 if(!multimode_dispflags[1]) mask = mask | 0x0f0;
145                                 if(!multimode_dispflags[2]) mask = mask | 0xf00;
146                                 if(pp != NULL) pp = &(pp[begin]);
147                                 p = &(p[begin]);
148                                 uint32_t yoff = y * 40 + begin;
149                                 for(int x = begin; x < (begin + bytes); x++) {
150                                         GETVRAM_4096(yoff, p, pp, mask, window_inv, scan_line);
151 #    if defined(FIXED_FRAMEBUFFER_SIZE)
152                                         p += 16;
153                                         if(pp != NULL) pp += 16;
154 #    else
155                                         p += 8;
156 #    endif
157                                         yoff++;
158                                 }
159                         }
160                         break;
161 #    if defined(_FM77AV40EX) || defined(_FM77AV40SX) || defined(_FM77AV40)
162                 case DISPLAY_MODE_256k:
163                         {
164                                 uint32_t yoff = y * 40;
165                                 if(pp != NULL) pp = &(pp[begin]);
166                                 p = &(p[begin]);
167                                 for(int x = begin; x < (begin + bytes); x++) {
168                                         GETVRAM_256k(yoff + x, p, pp, scan_line);
169 #      if defined(FIXED_FRAMEBUFFER_SIZE)
170                                         p += 16;
171                                         if(pp != NULL) pp += 16;
172 #      else
173                                         p += 8;
174 #      endif
175                                 }
176                         }
177                         break;
178 #    endif
179 #  endif
180                 default:
181                         break;
182                 }
183         }                       
184 }
185
186 #if defined(_FM77L4)
187 void DISPLAY::draw_77l4_400l(bool ff)
188 {
189         bool renderf = false;
190         uint32_t naddr;
191         uint8_t bitcode;
192         uint8_t charcode;
193         uint8_t attr_code;
194         scrntype_t on_color;
195         int xlim, ylim;
196         bool do_green;
197         uint8_t *regs = l4crtc->get_regs();
198         cursor_start = (int)(regs[10] & 0x1f);
199         cursor_end = (int)(regs[11] & 0x1f);
200         cursor_type = (int)((regs[10] & 0x60) >> 5);
201         text_xmax = (int)((uint16_t)regs[1] << 1);
202         text_lines = (int)((regs[9] & 0x1f) + 1);
203         text_ymax = (int)(regs[6] & 0x7f);
204         int yoff = 0;
205         scrntype_t *p;
206         for(int y =0; y < 400; y+= 8) {
207                 renderf = false;
208                 if((y & 0x0f) == 0) {
209                         for(int yy = 0; yy < 16; yy++) renderf |= vram_draw_table[y + yy];
210                         renderf = renderf | ff;
211                         if(renderf) {
212                                 for(int yy = 0; yy < 16; yy++) vram_draw_table[y + yy] = true;
213                         }
214                 }
215                 if(use_green_monitor) {
216                         for(int yy = 0; yy < 8; yy++) {
217                                 if(!(vram_draw_table[y + yy] | ff)) continue;
218                                 vram_draw_table[y + yy] = false;
219                                 p = emu->get_screen_buffer(y + yy);
220                                 if(p == NULL) continue;
221                                 yoff = (y + yy) * 80;
222                                 for(int x = 0; x < 10; x++) {
223                                         for(int ii = 0; ii < 8; ii++) {
224                                                 GETVRAM_1_400L_GREEN(yoff + ii, p);
225                                                 p += 8;
226                                         }
227                                         yoff += 8;
228                                 }
229                         }
230                         do_green = true;
231                 } else {
232                         for(int yy = 0; yy < 8; yy++) {
233                                 if(!(vram_draw_table[y + yy] | ff)) continue;
234                                 vram_draw_table[y + yy] = false;
235                                 p = emu->get_screen_buffer(y + yy);
236                                 if(p == NULL) continue;
237                                 yoff = (y + yy) * 80;
238                                 for(int x = 0; x < 10; x++) {
239                                         for(int ii = 0; ii < 8; ii++) {
240                                                 GETVRAM_1_400L(yoff + ii, p);
241                                                 p += 8;
242                                         }
243                                         yoff += 8;
244                                 }
245                         }
246                         do_green = false;
247                 }
248                 // Draw Text
249                 if(renderf) {
250                         bool reverse;
251                         bool display_char;
252                         int raster;
253                         bool cursor_rev;
254                         uint8_t bitdata;
255                         if(text_width40) {
256                                 xlim = 40;
257                         } else {
258                                 xlim = 80;
259                         }
260                                 
261                         for(int x = 0; x < xlim; x++) {
262                                 naddr = (text_start_addr.w.l + ((y / text_lines) * text_xmax + x) * 2) & 0x0ffe;
263                                 charcode = text_vram[naddr];
264                                 attr_code = text_vram[naddr + 1];
265                                                 
266                                 on_color = GETVRAM_TEXTCOLOR(attr_code, do_green);
267                                         
268                                 display_char = ((attr_code & 0x10) == 0);
269                                 reverse = ((attr_code & 0x08) != 0);
270                                         
271                                 for(int yy = 0; yy < 16; yy++) {
272                                         raster = y % text_lines;
273                                         bitdata = 0x00;
274                                         p = emu->get_screen_buffer(y + yy);
275                                         if(p == NULL) continue;
276                                         if((raster < 16) && (display_char || text_blink)) {
277                                                 bitdata = subsys_cg_l4[(uint32_t)charcode * 16 + (uint32_t)raster];
278                                         }
279                                         cursor_rev = false;
280                                         if((naddr == (uint32_t)(cursor_addr.w.l)) && (cursor_type != 1) &&
281                                            (text_blink || (cursor_type == 0))) {
282                                                 if((raster >= cursor_start) && (raster <= cursor_end)) {
283                                                         cursor_rev = true;
284                                                 }
285                                         }
286                                         bitdata = GETVRAM_TEXTPIX(bitdata, reverse, cursor_rev);
287                                         if(bitdata != 0) {
288                                                 if(text_width40) {
289                                                         scrntype_t *pp = &(p[x * 2]); 
290                                                         for(int ii = 0; ii < 8; ii++) {
291                                                                 if((bitdata & 0x80) != 0) {
292                                                                         p[0] = on_color;
293                                                                         p[1] = on_color;
294                                                                 }
295                                                                 bitdata <<= 1;
296                                                                 p += 2;
297                                                         }                                                                               
298                                                 } else {
299                                                         scrntype_t *pp = &(p[x * 2]); 
300                                                         for(int ii = 0; ii < 8; ii++) {
301                                                                 if((bitdata & 0x80) != 0) {
302                                                                         p[0] = on_color;
303                                                                 }
304                                                                 bitdata <<= 1;
305                                                                 p += 1;
306                                                         }                                                                               
307                                                 }
308                                         }
309                                 }
310                         }
311                 }
312         }
313 }
314 #endif
315
316 void DISPLAY::draw_screen()
317 {
318         uint16_t wx_begin = -1, wx_end = -1, wy_low = 1024, wy_high = -1;
319         bool scan_line = config.scan_line;
320         bool ff = force_update;
321         int dmode = display_mode;
322         yoff_d = 0;
323 #if defined(_FM77AV40EX) || defined(_FM77AV40SX)
324         {
325                 wx_begin = window_xbegin;
326                 wx_end   = window_xend;
327                 wy_low   = window_low;
328                 wy_high  = window_high;
329                 bool _flag = window_opened; 
330                 if((wx_begin < wx_end) && (wy_low < wy_high)) {
331                         window_opened = true;
332                 } else {
333                         window_opened = false;
334                 }
335                 if(_flag != window_opened) {
336                         vram_wrote_shadow = true;
337                 }
338         }
339 #endif
340 #if defined(_FM77AV_VARIANTS)
341         yoff_d2 = 0;
342         yoff_d1 = 0;
343 #else
344         //if(!(vram_wrote_shadow)) return;
345         yoff_d1 = yoff_d2 = offset_point;
346 #endif
347         int ylines;
348         int xpixels;
349         switch(dmode) {
350         case DISPLAY_MODE_8_200L:
351                 xpixels = 640;
352                 ylines = 200;
353                 break;
354         case DISPLAY_MODE_1_400L:
355         case DISPLAY_MODE_8_400L:
356                 xpixels = 640;
357                 ylines = 400;
358                 break;
359         default:
360                 xpixels = 320;
361                 ylines = 200;
362                 break;
363         }
364 # if !defined(FIXED_FRAMEBUFFER_SIZE)
365         emu->set_vm_screen_size(xpixels, ylines, WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_WIDTH_ASPECT, WINDOW_HEIGHT_ASPECT);
366 # endif
367         emu->set_vm_screen_lines(ylines);
368         if(!crt_flag) {
369                 if(crt_flag_bak) {
370                         clear_display(dmode, xpixels, ylines);
371                 }
372                 crt_flag_bak = crt_flag;
373                 if(ff) force_update = false;
374                 return;
375         }
376         crt_flag_bak = crt_flag;
377         if(!(vram_wrote_shadow | ff)) return;
378         vram_wrote_shadow = false;
379
380         int wpixels = xpixels >> 3;
381 #if defined(_FM77L4)
382         if(dmode == DISPLAY_MODE_1_400L) {
383                 draw_77l4_400l(ff);
384                 if(ff) force_update = false;
385                 return;
386         }
387 #endif  
388         for(int y = 0;  y < ylines; y += 8) {
389                 for(int yy = 0; yy < 8; yy++) {
390                         if(!(vram_draw_table[y + yy] | ff)) continue;
391                         vram_draw_table[y + yy] = false;
392 #  if defined(_FM77AV40EX) || defined(_FM77AV40SX) || defined(_FM77AV40)
393                                 int dpage;
394                                 dpage = vram_display_block;
395                                 bool window_inv = false;
396 #    if defined(_FM77AV40EX) || defined(_FM77AV40SX)
397                                 if((window_opened && (wy_low <= (y + yy)) && (wy_high > (y + yy)))
398                                    && (dmode != DISPLAY_MODE_256k)) {
399                                         if((wx_begin > 0) && (wx_begin < wx_end) && (wx_begin < wpixels)) {
400                                                 yoff_d = (dpage != 0) ? 0x18000 : 0x00000;
401                                                 if(display_page_bak == 1) yoff_d += 0xc000;
402                                                 draw_window(dmode, yy + y, 0, wx_begin,
403                                                                         false, scan_line);
404                                                 yoff_d = (dpage != 0) ? 0x00000 : 0x18000;
405                                                 if(display_page_bak == 1) yoff_d += 0xc000;
406                                                 draw_window(dmode, yy + y,
407                                                                         wx_begin, ((wx_end >= wpixels) ? wpixels : wx_end) - wx_begin,
408                                                                         true, scan_line);
409                                                 if(wx_end < wpixels) {
410                                                         yoff_d = (dpage != 0) ? 0x18000 : 0x00000;
411                                                         if(display_page_bak == 1) yoff_d += 0xc000;
412                                                         draw_window(dmode, yy + y, wx_end,  wpixels - wx_end,
413                                                                                 false, scan_line);
414                                                 }
415                                         } else {
416                                                 yoff_d = (dpage != 0) ? 0x00000 : 0x18000;
417                                                 if(display_page_bak == 1) yoff_d += 0xc000;
418                                                 draw_window(dmode, yy + y, 0, wx_end,
419                                                                         false, scan_line);
420                                                 if(wx_end < wpixels) {
421                                                         yoff_d = (dpage != 0) ? 0x18000 : 0x00000;
422                                                         if(display_page_bak == 1) yoff_d += 0xc000;
423                                                         draw_window(dmode, yy + y, wx_end , wpixels - wx_end,
424                                                                                 true, scan_line);
425                                                 }
426                                         }                                               
427                                 } else
428 #    endif
429                                 {
430                                         
431                                         yoff_d = (dpage != 0) ? 0x18000 : 0x00000;
432                                         if(display_page_bak == 1) yoff_d += 0xc000;
433                                         draw_window(dmode, yy + y, 0, wpixels, false, scan_line);
434                                 }
435                                 // Copy line
436 #elif defined(_FM77AV_VARIANTS)
437                                 yoff_d = 0;
438                                 if(display_page_bak == 1) yoff_d += 0xc000;
439                                 draw_window(dmode, yy + y, 0, wpixels, false, scan_line);
440 #else
441                                 yoff_d = 0;
442                                 draw_window(dmode, yy + y, 0, wpixels, false, scan_line);
443 #endif
444                 }
445         }
446         if(ff) force_update = false;
447         return;
448 }
449
450
451 bool DISPLAY::screen_update(void)
452 {
453         if(crt_flag) {
454                 bool f = screen_update_flag;
455                 screen_update_flag = false;
456                 return f;
457         } else {
458                 if(crt_flag_bak) return true;
459         }
460         return false;
461 }
462
463 void DISPLAY::reset_screen_update(void)
464 {
465         screen_update_flag = false;
466 }
467
468 void DISPLAY::CopyDrawnData(scrntype_t* src, scrntype_t* dst, int width, bool scan_line)
469 {
470         if(dst == NULL) return;
471         if(src == NULL) return;
472 #if defined(_RGB555) || defined(_RGBA565)
473         static const int shift_factor = 2;
474 #else // 24bit
475         static const int shift_factor = 3;
476 #endif
477         scrntype_vec8_t* vsrc = (scrntype_vec8_t*)src;
478         scrntype_vec8_t* vdst = (scrntype_vec8_t*)dst;
479         __DECL_ALIGNED(32) scrntype_vec8_t tmp_dd;
480         __DECL_ALIGNED(32) scrntype_vec8_t sline;
481         
482         if(scan_line) {
483 __DECL_VECTORIZED_LOOP
484                 for(int i = 0; i < 8; i++) {
485                         sline.w[i] = (scrntype_t)RGBA_COLOR(31, 31, 31, 255);
486                 }
487 __DECL_VECTORIZED_LOOP
488                 for(int i = 0; i < width; i++) {
489                         tmp_dd.v = vsrc[i].v;
490                         tmp_dd.v = tmp_dd.v >> shift_factor;
491                         tmp_dd.v = tmp_dd.v & sline.v;
492                         vdst[i].v = tmp_dd.v;
493                 }
494         } else {
495 __DECL_VECTORIZED_LOOP
496                 for(int i = 0; i < width; i++) {
497                         tmp_dd.v = vsrc[i].v;
498                         vdst[i].v = tmp_dd.v;
499                 }
500         }
501 }
502
503
504 #if defined(_FM77L4)
505 scrntype_t DISPLAY::GETVRAM_TEXTCOLOR(uint8_t attr, bool do_green)
506 {
507         int color = attr & 0x07;
508         int r, g, b;
509
510         static const int green_g_table[16] = {0, 24, 48, 64, 80, 96, 112, 128,
511                                                                                   140, 155, 175, 186, 210, 220, 240, 255};
512         if(do_green) {
513                 if((attr & 0x20) != 0) color += 8;
514                 r = b = 0;
515                 g = green_g_table[color];
516                 if(color >= 10) {
517                         r = (color - 9) * 16;
518                         b = (color - 9) * 16;
519                 }
520         } else {
521                 if((attr & 0x20) != 0) {
522                         g = ((color & 4) != 0) ? 255 : 0;
523                         r = ((color & 2) != 0) ? 255 : 0;
524                         b = ((color & 1) != 0) ? 255 : 0;
525                 } else {
526                         g = ((color & 4) != 0) ? 128 : 0;
527                         r = ((color & 2) != 0) ? 128 : 0;
528                         b = ((color & 1) != 0) ? 128 : 0;
529                 }
530         }
531         return RGBA_COLOR(r, g, b, 255);
532 }
533
534 uint8_t DISPLAY::GETVRAM_TEXTPIX(uint8_t bitdata, bool reverse, bool cursor_rev)
535 {
536         uint8_t ret = bitdata;
537         if(reverse) {
538                 ret = (uint8_t)(~ret);
539         }
540         if(cursor_rev) {
541             ret = (uint8_t)(~ret);
542         }
543         return ret;
544 }
545
546 void DISPLAY::GETVRAM_1_400L(int yoff, scrntype_t *p)
547 {
548         uint8_t pixel;
549         if(p == NULL) return;
550         yoff_d = yoff & 0x7fff;
551         pixel = gvram_shadow[yoff_d];
552         uint16_vec8_t *ppx = (uint16_vec8_t *)(&(bit_trans_table_0[pixel][0]));
553         __DECL_ALIGNED(16) uint16_vec8_t tmp_d;
554         __DECL_ALIGNED(32) scrntype_vec8_t tmp_dd;
555         scrntype_vec8_t *vp = (scrntype_vec8_t *)p;
556
557         tmp_d.v = ppx->v;
558         tmp_d.v = tmp_d.v >> 5;
559         
560 __DECL_VECTORIZED_LOOP
561         for(int i = 0; i < 8; i++) {
562                 tmp_dd.w[i] = dpalette_pixel[tmp_d.w[i]];
563         }
564
565         vp->v = tmp_dd.v;
566 }
567
568 void DISPLAY::GETVRAM_1_400L_GREEN(int yoff, scrntype_t *p)
569 {
570         uint8_t pixel;
571         if(p == NULL) return;
572         yoff_d = yoff & 0x7fff;
573         pixel = gvram_shadow[yoff_d];
574         uint16_vec8_t *ppx = (uint16_vec8_t *)(&(bit_trans_table_0[pixel][0]));
575         __DECL_ALIGNED(16) uint16_vec8_t tmp_d;
576         __DECL_ALIGNED(32) scrntype_vec8_t tmp_dd;
577         scrntype_vec8_t *vp = (scrntype_vec8_t *)p;
578
579         tmp_d.v = ppx->v;
580         tmp_d.v = tmp_d.v >> 5;
581         
582 __DECL_VECTORIZED_LOOP
583         for(int i = 0; i < 8; i++) {
584                 tmp_dd.w[i] = dpalette_pixel_green[tmp_d.w[i]];
585         }
586         vp->v = tmp_dd.v;
587
588 }
589 #endif
590
591
592 #if defined(_FM77AV_VARIANTS)
593 void DISPLAY::GETVRAM_4096(int yoff, scrntype_t *p, scrntype_t *px,
594                                                    uint32_t mask,
595                                                    bool window_inv,
596                                                    bool scan_line)
597 {
598         uint32_t b3, r3, g3;
599         uint8_t  bb[4], rr[4], gg[4];
600         __DECL_ALIGNED(16) uint16_vec8_t pixels;
601         __DECL_ALIGNED(16) const uint16_t __masks[8] = {(uint16_t)mask, (uint16_t)mask, (uint16_t)mask, (uint16_t)mask, (uint16_t)mask, (uint16_t)mask, (uint16_t)mask, (uint16_t)mask};
602         scrntype_t b, r, g;
603         uint32_t idx;;
604         scrntype_t pixel;
605 # if defined(_FM77AV40EX) || defined(_FM77AV40SX)
606         int dpage = vram_display_block;
607 # endif
608         if(p == NULL) return;
609         
610         yoff_d1 = yoff;
611         yoff_d2 = yoff;
612 # if defined(_FM77AV40EX) || defined(_FM77AV40SX)
613         if(window_inv) {
614                 if(dpage == 0) {
615                         dpage = 1;
616                 } else {
617                         dpage = 0;
618                 }
619         }
620         if(dpage != 0) {
621                 yoff_d1 += 0x18000;
622                 yoff_d2 += 0x18000;
623         }
624 # endif
625         bb[0] = gvram_shadow[yoff_d1];
626         bb[1] = gvram_shadow[yoff_d1 + 0x02000];
627         rr[0] = gvram_shadow[yoff_d1 + 0x04000];
628         rr[1] = gvram_shadow[yoff_d1 + 0x06000];
629         gg[0] = gvram_shadow[yoff_d1 + 0x08000];
630         gg[1] = gvram_shadow[yoff_d1 + 0x0a000];
631                 
632         bb[2] = gvram_shadow[yoff_d2 + 0x0c000];
633         bb[3] = gvram_shadow[yoff_d2 + 0x0e000];
634         rr[2] = gvram_shadow[yoff_d2 + 0x10000];
635         rr[3] = gvram_shadow[yoff_d2 + 0x12000];
636         gg[2] = gvram_shadow[yoff_d2 + 0x14000];
637         gg[3] = gvram_shadow[yoff_d2 + 0x16000];
638
639         uint16_t *p0, *p1, *p2, *p3;
640 #if !defined(FIXED_FRAMEBUFFER_SIZE)
641         __DECL_ALIGNED(sizeof(scrntype_t) * 8) scrntype_t tmp_dd[8];
642 #else
643         __DECL_ALIGNED(sizeof(scrntype_t) * 8) scrntype_t tmp_dd[16];
644 #endif
645         __DECL_ALIGNED(16) uint16_vec8_t tmp_g, tmp_r, tmp_b;
646         __v8hi *vp0, *vp1, *vp2, *vp3;
647         // G
648         vp0 = (__v8hi*)(&(bit_trans_table_0[gg[0]][0]));
649         vp1 = (__v8hi*)(&(bit_trans_table_1[gg[1]][0]));
650         vp2 = (__v8hi*)(&(bit_trans_table_2[gg[2]][0]));
651         vp3 = (__v8hi*)(&(bit_trans_table_3[gg[3]][0]));
652         tmp_g.v = *vp0;
653         tmp_g.v = tmp_g.v | *vp1;
654         tmp_g.v = tmp_g.v | *vp2;
655         tmp_g.v = tmp_g.v | *vp3;
656         // R
657         vp0 = (__v8hi*)(&(bit_trans_table_0[rr[0]][0]));
658         vp1 = (__v8hi*)(&(bit_trans_table_1[rr[1]][0]));
659         vp2 = (__v8hi*)(&(bit_trans_table_2[rr[2]][0]));
660         vp3 = (__v8hi*)(&(bit_trans_table_3[rr[3]][0]));
661         tmp_r.v = *vp0;
662         tmp_r.v = tmp_r.v | *vp1;
663         tmp_r.v = tmp_r.v | *vp2;
664         tmp_r.v = tmp_r.v | *vp3;
665
666         // B
667         vp0 = (__v8hi*)(&(bit_trans_table_0[bb[0]][0]));
668         vp1 = (__v8hi*)(&(bit_trans_table_1[bb[1]][0]));
669         vp2 = (__v8hi*)(&(bit_trans_table_2[bb[2]][0]));
670         vp3 = (__v8hi*)(&(bit_trans_table_3[bb[3]][0]));
671         tmp_b.v = *vp0;
672         tmp_b.v = tmp_b.v | *vp1;
673         tmp_b.v = tmp_b.v | *vp2;
674         tmp_b.v = tmp_b.v | *vp3;
675         
676         __v8hi *mp = (__v8hi*)__masks;
677         tmp_g.v = tmp_g.v << 4;
678         tmp_b.v = tmp_b.v >> 4;
679         pixels.v = tmp_b.v;
680         pixels.v = pixels.v | tmp_r.v;
681         pixels.v = pixels.v | tmp_g.v;
682         pixels.v = pixels.v & *mp;
683         
684
685         scrntype_vec8_t *vp = (scrntype_vec8_t*)p;
686         scrntype_vec8_t *dp = (scrntype_vec8_t*)tmp_dd;
687 #if !defined(FIXED_FRAMEBUFFER_SIZE)
688 __DECL_VECTORIZED_LOOP
689         for(int i = 0; i < 8; i++) {
690                 tmp_dd[i] = analog_palette_pixel[pixels[i]];
691         }
692         vp->v = dp->v;
693 #else
694 __DECL_VECTORIZED_LOOP
695         for(int i = 0; i < 8; i++) {
696                 tmp_dd[i * 2] = tmp_dd[i * 2 + 1] = analog_palette_pixel[pixels.w[i]];;
697         }
698         scrntype_vec8_t *vpx = (scrntype_vec8_t*)px;
699         __DECL_ALIGNED(32) scrntype_vec8_t vmask;
700 __DECL_VECTORIZED_LOOP
701         for(int i = 0; i < 2; i++) {
702                 vp[i].v = dp[i].v;
703         }
704         if(scan_line) {
705 /* Fancy scanline */
706 __DECL_VECTORIZED_LOOP
707                 for(int i = 0; i < 2; i++) {
708 #if defined(_RGB888) || defined(_RGBA888)
709                         dp[i].v = dp[i].v >> 3;
710 #elif defined(_RGB555)
711                         dp[i].v = dp[i].v >> 2;
712 #elif defined(_RGB565)
713                         dp[i].v = dp[i].v >> 2;
714 #endif
715                 }
716 __DECL_VECTORIZED_LOOP
717                 for(int i = 0; i < 8; i++) {
718                         vmask.w[i] = (const scrntype_t)RGBA_COLOR(31, 31, 31, 255);
719                 }
720 __DECL_VECTORIZED_LOOP
721                 for(int i = 0; i < 2; i++) {
722                         dp[i].v = dp[i].v & vmask.v; 
723                         vpx[i].v = dp[i].v;
724                 }
725         } else {
726 __DECL_VECTORIZED_LOOP
727                 for(int i = 0; i < 2; i++) {
728                         vpx[i].v = dp[i].v;
729                 }
730         }
731 #endif  
732 }
733 #endif
734
735 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
736
737 void DISPLAY::GETVRAM_256k(int yoff, scrntype_t *p, scrntype_t *px, bool scan_line)
738 {
739         uint32_t b3, r3, g3;
740         uint32_t b4, r4, g4;
741         uint32_t btmp, rtmp, gtmp;
742         
743         scrntype_t b, r, g;
744         scrntype_t pixel;
745         uint32_t _bit;
746         int _shift;
747         int cp;
748         if(p == NULL) return;
749         
750         r3 = g3 = b3 = 0;
751         r4 = g4 = b4 = 0;
752         r = g = b = 0;
753         
754         yoff_d1 = yoff;
755         yoff_d2 = yoff;
756
757         uint8_t  bb[8], rr[8], gg[8];
758
759         __DECL_ALIGNED(16) uint16_vec8_t _btmp;
760         __DECL_ALIGNED(16) uint16_vec8_t _rtmp;
761         __DECL_ALIGNED(16) uint16_vec8_t _gtmp;
762         uint16_vec8_t *vp0, *vp1, *vp2, *vp3, *vp4, *vp5;
763 #if !defined(FIXED_FRAMEBUFFER_SIZE)
764         __DECL_ALIGNED(sizeof(scrntype_t) * 8) scrntype_t tmp_dd[8];
765 #else
766         __DECL_ALIGNED(sizeof(scrntype_t) * 8) scrntype_t tmp_dd[16];
767 #endif
768 //      if(mask & 0x01) {
769         if(!multimode_dispflags[0]) {
770                 // B
771                 bb[0] = gvram_shadow[yoff_d1];
772                 bb[1] = gvram_shadow[yoff_d1 + 0x02000];
773                 
774                 bb[2] = gvram_shadow[yoff_d2 + 0x0c000];
775                 bb[3] = gvram_shadow[yoff_d2 + 0x0e000];
776         
777                 bb[4] = gvram_shadow[yoff_d1 + 0x18000];
778                 bb[5] = gvram_shadow[yoff_d1 + 0x1a000];
779                 
780                 vp0 = (uint16_vec8_t*)(&(bit_trans_table_0[bb[0]][0]));
781                 vp1 = (uint16_vec8_t*)(&(bit_trans_table_1[bb[1]][0]));
782                 vp2 = (uint16_vec8_t*)(&(bit_trans_table_2[bb[2]][0]));
783                 vp3 = (uint16_vec8_t*)(&(bit_trans_table_3[bb[3]][0]));
784                 vp4 = (uint16_vec8_t*)(&(bit_trans_table_4[bb[4]][0]));
785                 vp5 = (uint16_vec8_t*)(&(bit_trans_table_5[bb[5]][0]));
786                 _btmp.v = vp0->v;
787                 _btmp.v = _btmp.v | vp1->v;
788                 _btmp.v = _btmp.v | vp2->v;
789                 _btmp.v = _btmp.v | vp3->v;
790                 _btmp.v = _btmp.v | vp4->v;
791                 _btmp.v = _btmp.v | vp5->v;
792         } else {
793 __DECL_VECTORIZED_LOOP
794                 for(int i = 0; i < 8; i++) {
795                         _btmp.w[i] = 0;
796                 }
797         }
798         if(!multimode_dispflags[1]) {
799                 //if(mask & 0x02) {
800                 // R
801                 rr[0] = gvram_shadow[yoff_d1 + 0x04000];
802                 rr[1] = gvram_shadow[yoff_d1 + 0x06000];
803                 
804                 rr[2] = gvram_shadow[yoff_d2 + 0x10000];
805                 rr[3] = gvram_shadow[yoff_d2 + 0x12000];
806         
807                 rr[4] = gvram_shadow[yoff_d1 + 0x1c000];
808                 rr[5] = gvram_shadow[yoff_d1 + 0x1e000];
809                 
810                 vp0 = (uint16_vec8_t*)(&(bit_trans_table_0[rr[0]][0]));
811                 vp1 = (uint16_vec8_t*)(&(bit_trans_table_1[rr[1]][0]));
812                 vp2 = (uint16_vec8_t*)(&(bit_trans_table_2[rr[2]][0]));
813                 vp3 = (uint16_vec8_t*)(&(bit_trans_table_3[rr[3]][0]));
814                 vp4 = (uint16_vec8_t*)(&(bit_trans_table_4[rr[4]][0]));
815                 vp5 = (uint16_vec8_t*)(&(bit_trans_table_5[rr[5]][0]));
816                 _rtmp.v = vp0->v;
817                 _rtmp.v = _rtmp.v | vp1->v;
818                 _rtmp.v = _rtmp.v | vp2->v;
819                 _rtmp.v = _rtmp.v | vp3->v;
820                 _rtmp.v = _rtmp.v | vp4->v;
821                 _rtmp.v = _rtmp.v | vp5->v;
822         } else {
823 __DECL_VECTORIZED_LOOP
824                 for(int i = 0; i < 8; i++) {
825                         _rtmp.w[i] = 0;
826                 }
827         }
828         if(!multimode_dispflags[2]) {
829                 //if(mask & 0x04) {
830                 // G
831                 gg[0] = gvram_shadow[yoff_d1 + 0x08000];
832                 gg[1] = gvram_shadow[yoff_d1 + 0x0a000];
833                 
834                 gg[2] = gvram_shadow[yoff_d2 + 0x14000];
835                 gg[3] = gvram_shadow[yoff_d2 + 0x16000];
836         
837                 gg[4] = gvram_shadow[yoff_d1 + 0x20000];
838                 gg[5] = gvram_shadow[yoff_d1 + 0x22000];
839                 
840                 vp0 = (uint16_vec8_t*)(&(bit_trans_table_0[gg[0]][0]));
841                 vp1 = (uint16_vec8_t*)(&(bit_trans_table_1[gg[1]][0]));
842                 vp2 = (uint16_vec8_t*)(&(bit_trans_table_2[gg[2]][0]));
843                 vp3 = (uint16_vec8_t*)(&(bit_trans_table_3[gg[3]][0]));
844                 vp4 = (uint16_vec8_t*)(&(bit_trans_table_4[gg[4]][0]));
845                 vp5 = (uint16_vec8_t*)(&(bit_trans_table_5[gg[5]][0]));
846                 _gtmp.v = vp0->v;
847                 _gtmp.v = _gtmp.v | vp1->v;
848                 _gtmp.v = _gtmp.v | vp2->v;
849                 _gtmp.v = _gtmp.v | vp3->v;
850                 _gtmp.v = _gtmp.v | vp4->v;
851                 _gtmp.v = _gtmp.v | vp5->v;
852         } else {
853 __DECL_VECTORIZED_LOOP
854                 for(int i = 0; i < 8; i++) {
855                         _gtmp.w[i] = 0;
856                 }
857         }
858
859         scrntype_vec8_t* vpp = (scrntype_vec8_t*)p;
860         scrntype_vec8_t* dp = (scrntype_vec8_t*)tmp_dd;
861 #if !defined(FIXED_FRAMEBUFFER_SIZE)
862 __DECL_VECTORIZED_LOOP
863         for(int i = 0; i < 8; i++) {
864                 tmp_dd[i] = RGB_COLOR(_rtmp.w[i], _gtmp.w[i], _btmp.w[i]);
865         }
866         vpp->v = dp->v;
867 #else
868 __DECL_VECTORIZED_LOOP
869         for(int i = 0; i < 8; i++) {
870                 tmp_dd[i * 2] = tmp_dd[i * 2 + 1] = RGB_COLOR(_rtmp.w[i], _gtmp.w[i], _btmp.w[i]);
871         }
872
873 __DECL_VECTORIZED_LOOP
874         for(int i = 0; i < 2; i++) {
875                 vpp[i].v = dp[i].v;
876         }
877         scrntype_vec8_t* vpx = (scrntype_vec8_t*)px;
878         if(scan_line) {
879 /* Fancy scanline */
880 __DECL_VECTORIZED_LOOP
881                 for(int i = 0; i < 2; i++) {
882 #if defined(_RGB888) || defined(_RGBA888)
883                         dp[i].v = dp[i].v >> 3;
884 #elif defined(_RGB555)
885                         dp[i].v = dp[i].v >> 2;
886 #elif defined(_RGB565)
887                         dp[i].v = dp[i].v >> 2;
888 #endif
889                 }
890                 __DECL_ALIGNED(32) scrntype_vec8_t scanline_data;
891 __DECL_VECTORIZED_LOOP
892                 for(int i = 0; i < 8; i++) {
893                         scanline_data.w[i] = RGBA_COLOR(31, 31, 31, 255);
894                 }
895 __DECL_VECTORIZED_LOOP
896                 for(int i = 0; i < 2; i++) {
897                         dp[i].v = dp[i].v & scanline_data.v;
898                         vpx[i].v = dp[i].v;
899                 }
900         } else {
901                 for(int i = 0; i < 2; i++) {
902                         vpx[i].v = dp[i].v;
903                 }
904         }
905 #endif  
906 }
907 #endif
908
909 }