2 * Common source code project -> FM-7 -> Display -> Vram access
3 * (C) 2015 K.Ohta <whatisthis.sowhat _at_ gmail.com>
5 * Sep 27, 2015 : Split from display.cpp .
10 #include "fm7_display.h"
12 #include "../hd46505.h"
15 extern config_t config;
19 void DISPLAY::draw_screen()
21 //#if !defined(_FM77AV_VARIANTS)
26 void DISPLAY::draw_screen2()
30 scrntype_t *p, *pp, *p2;
35 uint32_t yoff_d1, yoff_d2;
36 uint16_t wx_begin, wx_end, wy_low, wy_high;
37 bool scan_line = config.scan_line;
38 bool ff = force_update;
40 #if defined(_FM77AV40EX) || defined(_FM77AV40SX)
42 wx_begin = window_xbegin;
45 wy_high = window_high;
46 bool _flag = window_opened;
47 if((wx_begin < wx_end) && (wy_low < wy_high)) {
50 window_opened = false;
52 if(_flag != window_opened) {
53 vram_wrote_shadow = true;
57 // frame_skip_count_draw++;
58 #if defined(_FM77AV_VARIANTS)
62 //if(!(vram_wrote_shadow)) return;
63 yoff_d1 = yoff_d2 = offset_point;
68 switch(display_mode) {
69 case DISPLAY_MODE_8_200L:
73 case DISPLAY_MODE_8_400L:
82 # if !defined(FIXED_FRAMEBUFFER_SIZE)
83 emu->set_vm_screen_size(xpixels, ylines, WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_WIDTH_ASPECT, WINDOW_HEIGHT_ASPECT);
85 emu->set_vm_screen_lines(ylines);
89 #if !defined(FIXED_FRAMEBUFFER_SIZE)
90 for(y = 0; y < ylines; y += 8) {
91 for(yy = 0; yy < 8; yy++) {
92 vram_draw_table[y + yy] = false;
93 ppp = emu->get_screen_buffer(y + yy);
94 if(ppp != NULL) memset(ppp, 0x00, xpixels * sizeof(scrntype_t));
98 for(y = 0; y < 400; y += 8) {
99 for(yy = 0; yy < 8; yy++) {
100 vram_draw_table[y + yy] = false;
101 ppp = emu->get_screen_buffer(y + yy);
102 if(ppp != NULL) memset(ppp, 0x00, 640 * sizeof(scrntype_t));
108 crt_flag_bak = crt_flag;
111 crt_flag_bak = crt_flag;
112 if(!(vram_wrote_shadow | ff)) return;
113 vram_wrote_shadow = false;
114 if(display_mode == DISPLAY_MODE_8_200L) {
115 _render_command_data_t cmd;
119 #if defined(USE_GREEN_DISPLAY)
120 if(use_green_monitor) {
121 cmd.palette = dpalette_pixel_green;
123 cmd.palette = dpalette_pixel;
126 cmd.palette = dpalette_pixel;
128 for(int i = 0; i < 3; i++) {
129 cmd.data[i] = gvram_shadow;
130 cmd.baseaddress[i] = i * 0x4000;
131 cmd.voffset[i] = yoff;
132 cmd.is_render[i] = false;
134 if(!multimode_dispflags[0]) cmd.is_render[0] = true;
135 if(!multimode_dispflags[1]) cmd.is_render[1] = true;
136 if(!multimode_dispflags[2]) cmd.is_render[2] = true;
137 cmd.bit_trans_table[0] = (_bit_trans_table_t*)(&(bit_trans_table_2[0][0])); // B
138 cmd.bit_trans_table[1] = (_bit_trans_table_t*)(&(bit_trans_table_1[0][0])); // R
139 cmd.bit_trans_table[2] = (_bit_trans_table_t*)(&(bit_trans_table_0[0][0])); // G
141 cmd.addrmask = 0x3fff;
142 cmd.addrmask2 = 0x3fff;
145 cmd.render_width = 80;
146 for(y = 0; y < 200; y += 8) {
147 for(yy = 0; yy < 8; yy++) {
149 if(!(vram_draw_table[y + yy] | ff)) continue;
150 vram_draw_table[y + yy] = false;
151 #if !defined(FIXED_FRAMEBUFFER_SIZE)
152 p = emu->get_screen_buffer(y + yy);
155 p = emu->get_screen_buffer((y + yy) * 2);
156 p2 = emu->get_screen_buffer((y + yy) * 2 + 1);
158 if(p == NULL) continue;
159 yoff = (y + yy) * 80;
160 for(int i = 0; i < 3; i++) {
161 cmd.voffset[i] = yoff;
164 # if defined(_FM77AV40EX) || defined(_FM77AV40SX)
166 dpage = vram_display_block;
167 bool window_inv = false;
168 if(window_opened && (wy_low <= (y + yy)) && (wy_high > (y + yy))) {
169 if((wx_begin > 0) && (wx_begin < wx_end) && (wx_begin < 80)) {
174 if(_wend >= 80) _wend = 80;
175 cmd.render_width = wx_begin;
176 yoff_d = (dpage != 0) ? 0x18000 : 0x00000;
177 #if defined(_FM77AV_VARIANTS)
178 if(display_page_bak == 1) yoff_d += 0xc000;
180 for(int i = 0; i < 3; i++) {
181 cmd.baseaddress[i] = yoff_d + (i * 0x4000);
183 if(cmd.render_width > 0) {
184 if(cmd.render_width > 80) cmd.render_width = 80;
186 Render8Colors_Line(&cmd, p, p2, scan_line);
189 cmd.begin_pos = wx_begin;
190 cmd.render_width = _wend - wx_begin;
191 yoff_d = (dpage != 0) ? 0x00000 : 0x18000;
192 #if defined(_FM77AV_VARIANTS)
193 if(display_page_bak == 1) yoff_d += 0xc000;
195 for(int i = 0; i < 3; i++) {
196 cmd.baseaddress[i] = yoff_d + (i * 0x4000);
198 if(cmd.render_width > 0) {
199 if(cmd.render_width > 80) cmd.render_width = 80;
201 Render8Colors_Line(&cmd, &(p[cmd.begin_pos * 8]), &(p2[cmd.begin_pos * 8]) , scan_line);
204 cmd.begin_pos = wx_end;
205 cmd.render_width = 80 - wx_end;
206 yoff_d = (dpage != 0) ? 0x18000 : 0x00000;
207 #if defined(_FM77AV_VARIANTS)
208 if(display_page_bak == 1) yoff_d += 0xc000;
210 for(int i = 0; i < 3; i++) {
211 cmd.baseaddress[i] = yoff_d + (i * 0x4000);
213 if(cmd.render_width > 0) {
214 if(cmd.render_width > 80) cmd.render_width = 80;
216 Render8Colors_Line(&cmd, &(p[cmd.begin_pos * 8]), &(p2[cmd.begin_pos * 8]), scan_line);
218 #if defined(FIXED_FRAMEBUFFER_SIZE)
219 //CopyDrawnData(p, p2, 80, scan_line);
222 } else if((wx_begin <= 0) && (wx_begin < wx_end) && (wx_end >= 0)) {
225 cmd.render_width = wx_end;
226 yoff_d = (dpage != 0) ? 0x00000 : 0x18000;
227 #if defined(_FM77AV_VARIANTS)
228 if(display_page_bak == 1) yoff_d += 0xc000;
230 for(int i = 0; i < 3; i++) {
231 cmd.baseaddress[i] = yoff_d + (i * 0x4000);
233 if(cmd.render_width > 0) {
234 if(cmd.render_width > 80) cmd.render_width = 80;
236 if(cmd.render_width > 0) Render8Colors_Line(&cmd, &(p[cmd.begin_pos * 8]), &(p2[cmd.begin_pos * 8]), scan_line);
239 cmd.begin_pos = wx_end;
240 cmd.render_width = 80 - wx_end;
241 yoff_d = (dpage != 0) ? 0x18000 : 0x00000;
242 #if defined(_FM77AV_VARIANTS)
243 if(display_page_bak == 1) yoff_d += 0xc000;
245 for(int i = 0; i < 3; i++) {
246 cmd.baseaddress[i] = yoff_d + (i * 0x4000);
248 if(cmd.render_width > 0) {
249 if(cmd.render_width > 80) cmd.render_width = 80;
251 Render8Colors_Line(&cmd, &(p[cmd.begin_pos * 8]), &(p2[cmd.begin_pos * 8]), scan_line);
253 #if defined(FIXED_FRAMEBUFFER_SIZE)
254 // CopyDrawnData(p, p2, 80, scan_line);
261 //cmd.render_width = 80;
262 # if defined(_FM77AV40EX) || defined(_FM77AV40SX)
263 yoff_d = (dpage != 0) ? 0x18000 : 0x00000;
267 #if defined(_FM77AV_VARIANTS)
268 if(display_page_bak == 1) yoff_d += 0xc000;
269 for(int i = 0; i < 3; i++) {
270 cmd.baseaddress[i] = yoff_d + (i * 0x4000);
273 // for(int i = 0; i < 3; i++) {
274 // cmd.baseaddress[i] = i * 0x4000;
278 Render8Colors_Line(&cmd, p, p2, scan_line);
279 #if defined(FIXED_FRAMEBUFFER_SIZE)
280 //CopyDrawnData(p, p2, 80, scan_line);
284 if(ff) force_update = false;
288 if(display_mode == DISPLAY_MODE_1_400L) {
290 uint8_t *regs = l4crtc->get_regs();
291 cursor_start = (int)(regs[10] & 0x1f);
292 cursor_end = (int)(regs[11] & 0x1f);
293 cursor_type = (int)((regs[10] & 0x60) >> 5);
294 text_xmax = (int)((uint16_t)regs[1] << 1);
295 text_lines = (int)((regs[9] & 0x1f) + 1);
296 text_ymax = (int)(regs[6] & 0x7f);
298 // Green display had only connected to FM-8, FM-7/NEW7 and FM-77.
299 for(y = 0; y < 400; y += 8) {
300 bool renderf = false;
308 if((y & 0x0f) == 0) {
309 for(yy = 0; yy < 16; yy++) renderf |= vram_draw_table[y + yy];
310 renderf = renderf | ff;
312 for(yy = 0; yy < 16; yy++) vram_draw_table[y + yy] = true;
315 if(use_green_monitor) {
316 for(yy = 0; yy < 8; yy++) {
317 if(!(vram_draw_table[y + yy] | ff)) continue;
318 vram_draw_table[y + yy] = false;
319 p = emu->get_screen_buffer(y + yy);
320 if(p == NULL) continue;
321 yoff = (y + yy) * 80;
322 for(x = 0; x < 10; x++) {
323 for(ii = 0; ii < 8; ii++) {
324 GETVRAM_1_400L_GREEN(yoff + ii, p);
332 for(yy = 0; yy < 8; yy++) {
333 if(!(vram_draw_table[y + yy] | ff)) continue;
334 vram_draw_table[y + yy] = false;
335 p = emu->get_screen_buffer(y + yy);
336 if(p == NULL) continue;
337 yoff = (y + yy) * 80;
338 for(x = 0; x < 10; x++) {
339 for(ii = 0; ii < 8; ii++) {
340 GETVRAM_1_400L(yoff + ii, p);
361 for(x = 0; x < xlim; x++) {
362 naddr = (text_start_addr.w.l + ((y / text_lines) * text_xmax + x) * 2) & 0x0ffe;
363 charcode = text_vram[naddr];
364 attr_code = text_vram[naddr + 1];
366 on_color = GETVRAM_TEXTCOLOR(attr_code, do_green);
368 display_char = ((attr_code & 0x10) == 0);
369 reverse = ((attr_code & 0x08) != 0);
371 for(yy = 0; yy < 16; yy++) {
372 raster = y % text_lines;
374 p = emu->get_screen_buffer(y + yy);
375 if(p == NULL) continue;
376 if((raster < 16) && (display_char || text_blink)) {
377 bitdata = subsys_cg_l4[(uint32_t)charcode * 16 + (uint32_t)raster];
380 if((naddr == (uint32_t)(cursor_addr.w.l)) && (cursor_type != 1) &&
381 (text_blink || (cursor_type == 0))) {
382 if((raster >= cursor_start) && (raster <= cursor_end)) {
386 bitdata = GETVRAM_TEXTPIX(bitdata, reverse, cursor_rev);
389 scrntype_t *pp = &(p[x * 2]);
390 for(ii = 0; ii < 8; ii++) {
391 if((bitdata & 0x80) != 0) {
399 scrntype_t *pp = &(p[x * 2]);
400 for(ii = 0; ii < 8; ii++) {
401 if((bitdata & 0x80) != 0) {
413 if(ff) force_update = false;
417 # if defined(_FM77AV_VARIANTS)
418 if(display_mode == DISPLAY_MODE_4096) {
422 if(!multimode_dispflags[0]) mask = 0x00f;
423 if(!multimode_dispflags[1]) mask = mask | 0x0f0;
424 if(!multimode_dispflags[2]) mask = mask | 0xf00;
425 for(y = 0; y < 200; y += 4) {
426 for(yy = 0; yy < 4; yy++) {
427 if(!(vram_draw_table[y + yy] | ff)) continue;
428 vram_draw_table[y + yy] = false;
430 #if !defined(FIXED_FRAMEBUFFER_SIZE)
431 p = emu->get_screen_buffer(y + yy);
434 p = emu->get_screen_buffer((y + yy) * 2 );
435 p2 = emu->get_screen_buffer((y + yy) * 2 + 1);
437 if(p == NULL) continue;
438 yoff = (y + yy) * 40;
439 # if defined(_FM77AV40EX) || defined(_FM77AV40SX)
440 if(window_opened && (wy_low <= (y + yy)) && (wy_high > (y + yy))) {
441 for(x = 0; x < 40; x++) {
442 if((x >= wx_begin) && (x < wx_end)) {
443 GETVRAM_4096(yoff, p, p2, mask, true, scan_line);
445 GETVRAM_4096(yoff, p, p2, mask, false, scan_line);
447 #if defined(FIXED_FRAMEBUFFER_SIZE)
458 for(x = 0; x < 5; x++) {
459 for(ii = 0; ii < 8; ii++) {
460 GETVRAM_4096(yoff + ii, p, p2, mask, false, scan_line);
461 #if defined(FIXED_FRAMEBUFFER_SIZE)
474 if(ff) force_update = false;
477 # if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
478 else if(display_mode == DISPLAY_MODE_8_400L) {
479 _render_command_data_t cmd;
482 cmd.palette = dpalette_pixel;
483 for(int i = 0; i < 3; i++) {
484 cmd.data[i] = gvram_shadow;
485 cmd.baseaddress[i] = i * 0x8000;
486 cmd.voffset[i] = yoff;
487 cmd.is_render[i] = false;
489 if(!multimode_dispflags[0]) cmd.is_render[0] = true;
490 if(!multimode_dispflags[1]) cmd.is_render[1] = true;
491 if(!multimode_dispflags[2]) cmd.is_render[2] = true;
492 cmd.bit_trans_table[0] = (_bit_trans_table_t*)(&(bit_trans_table_2[0][0])); // B
493 cmd.bit_trans_table[1] = (_bit_trans_table_t*)(&(bit_trans_table_1[0][0])); // R
494 cmd.bit_trans_table[2] = (_bit_trans_table_t*)(&(bit_trans_table_0[0][0])); // G
496 cmd.addrmask = 0x7fff;
497 cmd.addrmask2 = 0x7fff;
500 cmd.render_width = 80;
501 for(y = 0; y < 400; y += 8) {
502 for(yy = 0; yy < 8; yy++) {
503 if(!(vram_draw_table[y + yy] | ff)) continue;
504 vram_draw_table[y + yy] = false;
506 p = emu->get_screen_buffer(y + yy);
507 if(p == NULL) continue;
509 yoff = (y + yy) * 80;
510 for(int i = 0; i < 3; i++) {
511 cmd.voffset[i] = yoff;
514 bool window_inv = false;
516 dpage = vram_display_block;
517 # if defined(_FM77AV40EX) || defined(_FM77AV40SX)
518 if(window_opened && (wy_low <= (y + yy)) && (wy_high > (y + yy))) {
519 if((wx_begin > 0) && (wx_begin < wx_end) && (wx_begin < 80)) {
524 if(_wend >= 80) _wend = 80;
525 cmd.render_width = wx_begin;
526 yoff_d = (dpage != 0) ? 0x18000 : 0x00000;
527 for(int i = 0; i < 3; i++) {
528 cmd.baseaddress[i] = yoff_d + (i * 0x8000);
530 if(cmd.render_width > 0) {
531 if(cmd.render_width > 80) cmd.render_width = 80;
533 Render8Colors_Line(&cmd, p, NULL, false);
536 cmd.begin_pos = wx_begin;
537 cmd.render_width = _wend - wx_begin;
538 yoff_d = (dpage != 0) ? 0x00000 : 0x18000;
539 if(display_page_bak == 1) yoff_d += 0xc000;
540 for(int i = 0; i < 3; i++) {
541 cmd.baseaddress[i] = yoff_d + (i * 0x8000);
543 if(cmd.render_width > 0) {
544 if(cmd.render_width > 80) cmd.render_width = 80;
546 Render8Colors_Line(&cmd, &(p[cmd.begin_pos * 8]), NULL, false);
549 cmd.begin_pos = wx_end;
550 cmd.render_width = 80 - wx_end;
551 yoff_d = (dpage != 0) ? 0x18000 : 0x00000;
552 for(int i = 0; i < 3; i++) {
553 cmd.baseaddress[i] = yoff_d + (i * 0x8000);
555 if(cmd.render_width > 0) {
556 if(cmd.render_width > 80) cmd.render_width = 80;
558 Render8Colors_Line(&cmd, &(p[cmd.begin_pos * 8]), NULL, false);
561 } else if((wx_begin <= 0) && (wx_begin < wx_end) && (wx_end >= 0)) {
564 cmd.render_width = wx_end;
565 yoff_d = (dpage != 0) ? 0x00000 : 0x18000;
566 for(int i = 0; i < 3; i++) {
567 cmd.baseaddress[i] = yoff_d + (i * 0x8000);
569 if(cmd.render_width > 0) {
570 if(cmd.render_width > 80) cmd.render_width = 80;
572 if(cmd.render_width > 0) Render8Colors_Line(&cmd, &(p[cmd.begin_pos * 8]), NULL, false);
575 cmd.begin_pos = wx_end;
576 cmd.render_width = 80 - wx_end;
577 yoff_d = (dpage != 0) ? 0x18000 : 0x00000;
578 for(int i = 0; i < 3; i++) {
579 cmd.baseaddress[i] = yoff_d + (i * 0x8000);
581 if(cmd.render_width > 0) {
582 if(cmd.render_width > 80) cmd.render_width = 80;
584 Render8Colors_Line(&cmd, &(p[cmd.begin_pos * 8]), NULL, false);
592 cmd.render_width = 80;
593 yoff_d = (dpage != 0) ? 0x18000 : 0x00000;
594 for(int i = 0; i < 3; i++) {
595 cmd.baseaddress[i] = yoff_d + (i * 0x8000);
597 if(cmd.render_width > 0) {
598 if(cmd.render_width > 80) cmd.render_width = 80;
600 Render8Colors_Line(&cmd, &(p[cmd.begin_pos * 8]), NULL, false);
603 if(ff) force_update = false;
605 } else if(display_mode == DISPLAY_MODE_256k) {
607 //rgbmask = ~multimode_dispmask;
609 for(y = 0; y < 200; y += 4) {
610 for(yy = 0; yy < 4; yy++) {
611 if(!(vram_draw_table[y + yy] | ff)) continue;
612 vram_draw_table[y + yy] = false;
613 #if !defined(FIXED_FRAMEBUFFER_SIZE)
614 p = emu->get_screen_buffer(y + yy);
617 p = emu->get_screen_buffer((y + yy) * 2 );
618 p2 = emu->get_screen_buffer((y + yy) * 2 + 1);
620 if(p == NULL) continue;
622 yoff = (y + yy) * 40;
624 for(x = 0; x < 5; x++) {
625 for(ii = 0; ii < 8; ii++) {
626 GETVRAM_256k(yoff + ii, p, p2, scan_line);
627 #if !defined(FIXED_FRAMEBUFFER_SIZE)
639 if(ff) force_update = false;
643 # endif //_FM77AV_VARIANTS
646 bool DISPLAY::screen_update(void)
649 bool f = screen_update_flag;
650 screen_update_flag = false;
653 if(crt_flag_bak) return true;
658 void DISPLAY::reset_screen_update(void)
660 screen_update_flag = false;
663 void DISPLAY::CopyDrawnData(scrntype_t* src, scrntype_t* dst, int width, bool scan_line)
665 if(dst == NULL) return;
666 if(src == NULL) return;
667 #if defined(_RGB555) || defined(_RGBA565)
668 static const int shift_factor = 2;
670 static const int shift_factor = 3;
672 scrntype_vec8_t* vsrc = (scrntype_vec8_t*)__builtin_assume_aligned(src, sizeof(scrntype_vec8_t));
673 scrntype_vec8_t* vdst = (scrntype_vec8_t*)__builtin_assume_aligned(dst, sizeof(scrntype_vec8_t));
674 scrntype_vec8_t tmp_dd;
675 scrntype_vec8_t sline;
678 __DECL_VECTORIZED_LOOP
679 for(int i = 0; i < 8; i++) {
680 sline.w[i] = (scrntype_t)RGBA_COLOR(31, 31, 31, 255);
682 __DECL_VECTORIZED_LOOP
683 for(int i = 0; i < width; i++) {
684 tmp_dd.v = vsrc[i].v;
685 tmp_dd.v = tmp_dd.v >> shift_factor;
686 tmp_dd.v = tmp_dd.v & sline.v;
687 vdst[i].v = tmp_dd.v;
690 __DECL_VECTORIZED_LOOP
691 for(int i = 0; i < width; i++) {
692 tmp_dd.v = vsrc[i].v;
693 vdst[i].v = tmp_dd.v;
700 scrntype_t DISPLAY::GETVRAM_TEXTCOLOR(uint8_t attr, bool do_green)
702 int color = attr & 0x07;
705 static const int green_g_table[16] = {0, 24, 48, 64, 80, 96, 112, 128,
706 140, 155, 175, 186, 210, 220, 240, 255};
708 if((attr & 0x20) != 0) color += 8;
710 g = green_g_table[color];
712 r = (color - 9) * 16;
713 b = (color - 9) * 16;
716 if((attr & 0x20) != 0) {
717 g = ((color & 4) != 0) ? 255 : 0;
718 r = ((color & 2) != 0) ? 255 : 0;
719 b = ((color & 1) != 0) ? 255 : 0;
721 g = ((color & 4) != 0) ? 128 : 0;
722 r = ((color & 2) != 0) ? 128 : 0;
723 b = ((color & 1) != 0) ? 128 : 0;
726 return RGBA_COLOR(r, g, b, 255);
729 uint8_t DISPLAY::GETVRAM_TEXTPIX(uint8_t bitdata, bool reverse, bool cursor_rev)
731 uint8_t ret = bitdata;
733 ret = (uint8_t)(~ret);
736 ret = (uint8_t)(~ret);
741 void DISPLAY::GETVRAM_1_400L(int yoff, scrntype_t *p)
745 if(p == NULL) return;
746 yoff_d = yoff & 0x7fff;
747 pixel = gvram_shadow[yoff_d];
748 uint16_vec8_t *ppx = (uint16_vec8_t *)__builtin_assume_aligned(&(bit_trans_table_0[pixel][0]), 16);
749 __DECL_ALIGNED(16) uint16_vec8_t tmp_d;
750 scrntype_vec8_t tmp_dd;
751 scrntype_vec8_t *vp = (scrntype_vec8_t *)__builtin_assume_aligned(p, sizeof(scrntype_vec8_t));
754 tmp_d.v = tmp_d.v >> 5;
756 __DECL_VECTORIZED_LOOP
757 for(int i = 0; i < 8; i++) {
758 tmp_dd.w[i] = dpalette_pixel[tmp_d.w[i]];
764 void DISPLAY::GETVRAM_1_400L_GREEN(int yoff, scrntype_t *p)
768 if(p == NULL) return;
769 yoff_d = yoff & 0x7fff;
770 pixel = gvram_shadow[yoff_d];
771 uint16_vec8_t *ppx = (uint16_vec8_t *)__builtin_assume_aligned(&(bit_trans_table_0[pixel][0]), 16);
772 __DECL_ALIGNED(16) uint16_vec8_t tmp_d;
773 scrntype_vec8_t tmp_dd;
774 scrntype_vec8_t *vp = (scrntype_vec8_t *)__builtin_assume_aligned(p, sizeof(scrntype_vec8_t));
777 tmp_d.v = tmp_d.v >> 5;
779 __DECL_VECTORIZED_LOOP
780 for(int i = 0; i < 8; i++) {
781 tmp_dd.w[i] = dpalette_pixel_green[tmp_d.w[i]];
789 #if defined(_FM77AV_VARIANTS)
790 void DISPLAY::GETVRAM_4096(int yoff, scrntype_t *p, scrntype_t *px,
796 uint8_t bb[4], rr[4], gg[4];
797 uint16_vec8_t pixels;
798 __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};
804 # if defined(_FM77AV40EX) || defined(_FM77AV40SX)
805 int dpage = vram_display_block;
807 if(p == NULL) return;
811 # if defined(_FM77AV40EX) || defined(_FM77AV40SX)
824 bb[0] = gvram_shadow[yoff_d1];
825 bb[1] = gvram_shadow[yoff_d1 + 0x02000];
826 rr[0] = gvram_shadow[yoff_d1 + 0x04000];
827 rr[1] = gvram_shadow[yoff_d1 + 0x06000];
828 gg[0] = gvram_shadow[yoff_d1 + 0x08000];
829 gg[1] = gvram_shadow[yoff_d1 + 0x0a000];
831 bb[2] = gvram_shadow[yoff_d2 + 0x0c000];
832 bb[3] = gvram_shadow[yoff_d2 + 0x0e000];
833 rr[2] = gvram_shadow[yoff_d2 + 0x10000];
834 rr[3] = gvram_shadow[yoff_d2 + 0x12000];
835 gg[2] = gvram_shadow[yoff_d2 + 0x14000];
836 gg[3] = gvram_shadow[yoff_d2 + 0x16000];
838 uint16_t *p0, *p1, *p2, *p3;
839 #if !defined(FIXED_FRAMEBUFFER_SIZE)
840 __DECL_ALIGNED(sizeof(scrntype_t) * 8) scrntype_t tmp_dd[8];
842 __DECL_ALIGNED(sizeof(scrntype_t) * 8) scrntype_t tmp_dd[16];
844 uint16_vec8_t tmp_g, tmp_r, tmp_b;
845 __v8hi *vp0, *vp1, *vp2, *vp3;
847 vp0 = (__v8hi*)__builtin_assume_aligned(&(bit_trans_table_0[gg[0]][0]), 16);
848 vp1 = (__v8hi*)__builtin_assume_aligned(&(bit_trans_table_1[gg[1]][0]), 16);
849 vp2 = (__v8hi*)__builtin_assume_aligned(&(bit_trans_table_2[gg[2]][0]), 16);
850 vp3 = (__v8hi*)__builtin_assume_aligned(&(bit_trans_table_3[gg[3]][0]), 16);
852 tmp_g.v = tmp_g.v | *vp1;
853 tmp_g.v = tmp_g.v | *vp2;
854 tmp_g.v = tmp_g.v | *vp3;
856 vp0 = (__v8hi*)__builtin_assume_aligned(&(bit_trans_table_0[rr[0]][0]), 16);
857 vp1 = (__v8hi*)__builtin_assume_aligned(&(bit_trans_table_1[rr[1]][0]), 16);
858 vp2 = (__v8hi*)__builtin_assume_aligned(&(bit_trans_table_2[rr[2]][0]), 16);
859 vp3 = (__v8hi*)__builtin_assume_aligned(&(bit_trans_table_3[rr[3]][0]), 16);
861 tmp_r.v = tmp_r.v | *vp1;
862 tmp_r.v = tmp_r.v | *vp2;
863 tmp_r.v = tmp_r.v | *vp3;
866 vp0 = (__v8hi*)__builtin_assume_aligned(&(bit_trans_table_0[bb[0]][0]), 16);
867 vp1 = (__v8hi*)__builtin_assume_aligned(&(bit_trans_table_1[bb[1]][0]), 16);
868 vp2 = (__v8hi*)__builtin_assume_aligned(&(bit_trans_table_2[bb[2]][0]), 16);
869 vp3 = (__v8hi*)__builtin_assume_aligned(&(bit_trans_table_3[bb[3]][0]), 16);
871 tmp_b.v = tmp_b.v | *vp1;
872 tmp_b.v = tmp_b.v | *vp2;
873 tmp_b.v = tmp_b.v | *vp3;
875 __v8hi *mp = (__v8hi*)__masks;
876 tmp_g.v = tmp_g.v << 4;
877 tmp_b.v = tmp_b.v >> 4;
879 pixels.v = pixels.v | tmp_r.v;
880 pixels.v = pixels.v | tmp_g.v;
881 pixels.v = pixels.v & *mp;
884 scrntype_vec8_t *vp = (scrntype_vec8_t*)__builtin_assume_aligned(p, sizeof(scrntype_vec8_t));
885 scrntype_vec8_t *dp = (scrntype_vec8_t*)__builtin_assume_aligned(tmp_dd, sizeof(scrntype_vec8_t));
886 #if !defined(FIXED_FRAMEBUFFER_SIZE)
887 __DECL_VECTORIZED_LOOP
888 for(int i = 0; i < 8; i++) {
889 tmp_dd[i] = analog_palette_pixel[pixels[i]];
893 __DECL_VECTORIZED_LOOP
894 for(int i = 0; i < 8; i++) {
895 tmp_dd[i * 2] = tmp_dd[i * 2 + 1] = analog_palette_pixel[pixels.w[i]];;
897 scrntype_vec8_t *vpx = (scrntype_vec8_t*)__builtin_assume_aligned(px, sizeof(scrntype_vec8_t));
898 scrntype_vec8_t vmask;
899 __DECL_VECTORIZED_LOOP
900 for(int i = 0; i < 2; i++) {
905 __DECL_VECTORIZED_LOOP
906 for(int i = 0; i < 2; i++) {
907 #if defined(_RGB888) || defined(_RGBA888)
908 dp[i].v = dp[i].v >> 3;
909 #elif defined(_RGB555)
910 dp[i].v = dp[i].v >> 2;
911 #elif defined(_RGB565)
912 dp[i].v = dp[i].v >> 2;
915 __DECL_VECTORIZED_LOOP
916 for(int i = 0; i < 8; i++) {
917 vmask.w[i] = (const scrntype_t)RGBA_COLOR(31, 31, 31, 255);
919 __DECL_VECTORIZED_LOOP
920 for(int i = 0; i < 2; i++) {
921 dp[i].v = dp[i].v & vmask.v;
925 __DECL_VECTORIZED_LOOP
926 for(int i = 0; i < 2; i++) {
934 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
936 void DISPLAY::GETVRAM_256k(int yoff, scrntype_t *p, scrntype_t *px, bool scan_line)
940 uint32_t btmp, rtmp, gtmp;
949 if(p == NULL) return;
958 uint8_t bb[8], rr[8], gg[8];
963 uint16_vec8_t *vp0, *vp1, *vp2, *vp3, *vp4, *vp5;
964 #if !defined(FIXED_FRAMEBUFFER_SIZE)
965 __DECL_ALIGNED(sizeof(scrntype_t) * 8) scrntype_t tmp_dd[8];
967 __DECL_ALIGNED(sizeof(scrntype_t) * 8) scrntype_t tmp_dd[16];
970 if(!multimode_dispflags[0]) {
972 bb[0] = gvram_shadow[yoff_d1];
973 bb[1] = gvram_shadow[yoff_d1 + 0x02000];
975 bb[2] = gvram_shadow[yoff_d2 + 0x0c000];
976 bb[3] = gvram_shadow[yoff_d2 + 0x0e000];
978 bb[4] = gvram_shadow[yoff_d1 + 0x18000];
979 bb[5] = gvram_shadow[yoff_d1 + 0x1a000];
981 vp0 = (uint16_vec8_t*)__builtin_assume_aligned(&(bit_trans_table_0[bb[0]][0]), 16);
982 vp1 = (uint16_vec8_t*)__builtin_assume_aligned(&(bit_trans_table_1[bb[1]][0]), 16);
983 vp2 = (uint16_vec8_t*)__builtin_assume_aligned(&(bit_trans_table_2[bb[2]][0]), 16);
984 vp3 = (uint16_vec8_t*)__builtin_assume_aligned(&(bit_trans_table_3[bb[3]][0]), 16);
985 vp4 = (uint16_vec8_t*)__builtin_assume_aligned(&(bit_trans_table_4[bb[4]][0]), 16);
986 vp5 = (uint16_vec8_t*)__builtin_assume_aligned(&(bit_trans_table_5[bb[5]][0]), 16);
988 _btmp.v = _btmp.v | vp1->v;
989 _btmp.v = _btmp.v | vp2->v;
990 _btmp.v = _btmp.v | vp3->v;
991 _btmp.v = _btmp.v | vp4->v;
992 _btmp.v = _btmp.v | vp5->v;
994 __DECL_VECTORIZED_LOOP
995 for(int i = 0; i < 8; i++) {
999 if(!multimode_dispflags[1]) {
1002 rr[0] = gvram_shadow[yoff_d1 + 0x04000];
1003 rr[1] = gvram_shadow[yoff_d1 + 0x06000];
1005 rr[2] = gvram_shadow[yoff_d2 + 0x10000];
1006 rr[3] = gvram_shadow[yoff_d2 + 0x12000];
1008 rr[4] = gvram_shadow[yoff_d1 + 0x1c000];
1009 rr[5] = gvram_shadow[yoff_d1 + 0x1e000];
1011 vp0 = (uint16_vec8_t*)__builtin_assume_aligned(&(bit_trans_table_0[rr[0]][0]), 16);
1012 vp1 = (uint16_vec8_t*)__builtin_assume_aligned(&(bit_trans_table_1[rr[1]][0]), 16);
1013 vp2 = (uint16_vec8_t*)__builtin_assume_aligned(&(bit_trans_table_2[rr[2]][0]), 16);
1014 vp3 = (uint16_vec8_t*)__builtin_assume_aligned(&(bit_trans_table_3[rr[3]][0]), 16);
1015 vp4 = (uint16_vec8_t*)__builtin_assume_aligned(&(bit_trans_table_4[rr[4]][0]), 16);
1016 vp5 = (uint16_vec8_t*)__builtin_assume_aligned(&(bit_trans_table_5[rr[5]][0]), 16);
1018 _rtmp.v = _rtmp.v | vp1->v;
1019 _rtmp.v = _rtmp.v | vp2->v;
1020 _rtmp.v = _rtmp.v | vp3->v;
1021 _rtmp.v = _rtmp.v | vp4->v;
1022 _rtmp.v = _rtmp.v | vp5->v;
1024 __DECL_VECTORIZED_LOOP
1025 for(int i = 0; i < 8; i++) {
1029 if(!multimode_dispflags[2]) {
1032 gg[0] = gvram_shadow[yoff_d1 + 0x08000];
1033 gg[1] = gvram_shadow[yoff_d1 + 0x0a000];
1035 gg[2] = gvram_shadow[yoff_d2 + 0x14000];
1036 gg[3] = gvram_shadow[yoff_d2 + 0x16000];
1038 gg[4] = gvram_shadow[yoff_d1 + 0x20000];
1039 gg[5] = gvram_shadow[yoff_d1 + 0x22000];
1041 vp0 = (uint16_vec8_t*)__builtin_assume_aligned(&(bit_trans_table_0[gg[0]][0]), 16);
1042 vp1 = (uint16_vec8_t*)__builtin_assume_aligned(&(bit_trans_table_1[gg[1]][0]), 16);
1043 vp2 = (uint16_vec8_t*)__builtin_assume_aligned(&(bit_trans_table_2[gg[2]][0]), 16);
1044 vp3 = (uint16_vec8_t*)__builtin_assume_aligned(&(bit_trans_table_3[gg[3]][0]), 16);
1045 vp4 = (uint16_vec8_t*)__builtin_assume_aligned(&(bit_trans_table_4[gg[4]][0]), 16);
1046 vp5 = (uint16_vec8_t*)__builtin_assume_aligned(&(bit_trans_table_5[gg[5]][0]), 16);
1048 _gtmp.v = _gtmp.v | vp1->v;
1049 _gtmp.v = _gtmp.v | vp2->v;
1050 _gtmp.v = _gtmp.v | vp3->v;
1051 _gtmp.v = _gtmp.v | vp4->v;
1052 _gtmp.v = _gtmp.v | vp5->v;
1054 __DECL_VECTORIZED_LOOP
1055 for(int i = 0; i < 8; i++) {
1060 scrntype_vec8_t* vpp = (scrntype_vec8_t*)__builtin_assume_aligned(p, sizeof(scrntype_vec8_t));
1061 scrntype_vec8_t* dp = (scrntype_vec8_t*)tmp_dd;
1062 #if !defined(FIXED_FRAMEBUFFER_SIZE)
1063 __DECL_VECTORIZED_LOOP
1064 for(int i = 0; i < 8; i++) {
1065 tmp_dd[i] = RGB_COLOR(_rtmp.w[i], _gtmp.w[i], _btmp.w[i]);
1069 __DECL_VECTORIZED_LOOP
1070 for(int i = 0; i < 8; i++) {
1071 tmp_dd[i * 2] = tmp_dd[i * 2 + 1] = RGB_COLOR(_rtmp.w[i], _gtmp.w[i], _btmp.w[i]);
1074 __DECL_VECTORIZED_LOOP
1075 for(int i = 0; i < 2; i++) {
1078 scrntype_vec8_t* vpx = (scrntype_vec8_t*)__builtin_assume_aligned(px, sizeof(scrntype_vec8_t));
1080 /* Fancy scanline */
1081 __DECL_VECTORIZED_LOOP
1082 for(int i = 0; i < 2; i++) {
1083 #if defined(_RGB888) || defined(_RGBA888)
1084 dp[i].v = dp[i].v >> 3;
1085 #elif defined(_RGB555)
1086 dp[i].v = dp[i].v >> 2;
1087 #elif defined(_RGB565)
1088 dp[i].v = dp[i].v >> 2;
1091 scrntype_vec8_t scanline_data;
1092 __DECL_VECTORIZED_LOOP
1093 for(int i = 0; i < 8; i++) {
1094 scanline_data.w[i] = RGBA_COLOR(31, 31, 31, 255);
1096 __DECL_VECTORIZED_LOOP
1097 for(int i = 0; i < 2; i++) {
1098 dp[i].v = dp[i].v & scanline_data.v;
1102 for(int i = 0; i < 2; i++) {