OSDN Git Service

[VM][STATE] Apply new framework to some VMs.
[csp-qt/common_source_project-fm7.git] / source / src / vm / pasopia7 / display.cpp
index bf8f4d4..5889a5d 100644 (file)
-/*\r
-       TOSHIBA PASOPIA 7 Emulator 'EmuPIA7'\r
-\r
-       Author : Takeda.Toshiya\r
-       Date   : 2007.02.08 -\r
-\r
-       [ display ]\r
-*/\r
-\r
-#include "display.h"\r
-#include "../../fileio.h"\r
-\r
-void DISPLAY::initialize()\r
-{\r
-       scanline = config.scan_line;\r
-       \r
-       // load rom image\r
-       FILEIO* fio = new FILEIO();\r
-       if(fio->Fopen(emu->bios_path(_T("FONT.ROM")), FILEIO_READ_BINARY)) {\r
-               fio->Fread(font, sizeof(font), 1);\r
-               fio->Fclose();\r
-       }\r
-       delete fio;\r
-       \r
-       // create pc palette\r
-#ifdef _LCD\r
-       for(int i = 1; i < 8; i++) {\r
-               palette_pc[i] = RGB_COLOR(48, 56, 16);\r
-       }\r
-       palette_pc[0] = RGB_COLOR(160, 168, 160);\r
-#else\r
-       for(int i = 0; i < 8; i++) {\r
-               palette_pc[i] = RGB_COLOR((i & 2) ? 255 : 0, (i & 4) ? 255 : 0, (i & 1) ? 255 : 0);\r
-       }\r
-#endif\r
-       \r
-       // initialize\r
-       for(int i = 0; i < 16; i++) {\r
-               pal[i] = i & 7;\r
-       }\r
-       mode = text_page = 0;\r
-       cblink = flash_cnt = 0;\r
-       blink = pal_dis = false;\r
-       \r
-       // register event\r
-       register_frame_event(this);\r
-}\r
-\r
-void DISPLAY::update_config()\r
-{\r
-       scanline = config.scan_line;\r
-}\r
-\r
-void DISPLAY::write_signal(int id, uint32 data, uint32 mask)\r
-{\r
-       if(id == SIG_DISPLAY_I8255_0_A) {\r
-               mode = data;\r
-       } else if(id == SIG_DISPLAY_I8255_1_B) {\r
-               text_page = (data >> 4) & 7;\r
-       } else if(id == SIG_DISPLAY_I8255_1_C) {\r
-               blink = ((data & 0x20) != 0);\r
-               pal_dis = ((data & 8) != 0);\r
-       }\r
-}\r
-\r
-void DISPLAY::event_frame()\r
-{\r
-       cblink = (cblink + 1) & 0x1f;\r
-}\r
-\r
-void DISPLAY::draw_screen()\r
-{\r
-       // clear screen buffer\r
-       memset(screen, 0, sizeof(screen));\r
-       \r
-#ifdef _LCD\r
-       if((regs[8] & 0x30) != 0x30) {\r
-               // render screen\r
-               uint16 src = ((regs[12] << 11) | (regs[13] << 3)) & 0x3ff8;\r
-               if((regs[8] & 0xc0) == 0xc0) {\r
-                       cursor = -1;\r
-               } else {\r
-                       cursor = ((regs[14] << 11) | (regs[15] << 3)) & 0x3ff8;\r
-               }\r
-               \r
-               switch(mode & 0xa0) {\r
-               case 0x00:      // text, wide\r
-               case 0x20:      // text, normal\r
-                       draw_text_lcd(src);\r
-                       break;\r
-               case 0x80:      // fine graph, wide\r
-               case 0xa0:      // fine graph, normal\r
-                       draw_fine_lcd(src);\r
-                       break;\r
-               }\r
-       }\r
-       \r
-       // copy to real screen\r
-       for(int y = 0; y < 64; y++) {\r
-               scrntype* dest0 = emu->screen_buffer(y * 2 + 0);\r
-               scrntype* dest1 = emu->screen_buffer(y * 2 + 1);\r
-               uint8* src = screen[y];\r
-               \r
-               for(int x = 0; x < 320; x++) {\r
-                       dest0[x] = palette_pc[src[x] & 7];\r
-               }\r
-               if(scanline) {\r
-                       for(int x = 0; x < 320; x++) {\r
-                               dest1[x] = palette_pc[0];\r
-                       }\r
-               } else {\r
-                       memcpy(dest1, dest0, 320 * sizeof(scrntype));\r
-               }\r
-       }\r
-#else\r
-       if((regs[8] & 0x30) != 0x30) {\r
-               // sync check\r
-               uint16 flash = 0;\r
-               if(mode & 0x20) {\r
-                       if(regs[0] < 106 || 118 < regs[0] || 113 < regs[2]) {\r
-                               flash = 0xffff;\r
-                       }\r
-                       flash_cnt -= 320;\r
-               } else {\r
-                       if(regs[0] < 53 || 58 < regs[0] || 56 < regs[2]) {\r
-                               flash = 0xffff;\r
-                       }\r
-                       flash_cnt -= 160;\r
-               }\r
-               if(regs[4] < 27 || 32 < regs[4] || 16 < regs[5] || 32 < regs[7]) {\r
-                       flash = 0xffff;\r
-               }\r
-               if((regs[8] & 3) == 3 || (regs[9] != 7 && regs[9] != 6)) {\r
-                       flash = 0xffff;\r
-               }\r
-               uint16 src = (((regs[12] << 11) | (regs[13] << 3)) + (flash_cnt & flash)) & 0x3ff8;\r
-               if((regs[8] & 0xc0) == 0xc0) {\r
-                       cursor = -1;\r
-               } else {\r
-                       cursor = ((regs[14] << 11) | (regs[15] << 3)) & 0x3ff8;\r
-               }\r
-               \r
-               // render screen\r
-               if((flash != 0) || (regs[8] & 0x30) != 0x30) {\r
-                       switch(mode & 0xa0) {\r
-                       case 0x00:\r
-                               // text, wide\r
-                               draw_text_wide(src);\r
-                               flash_cnt += 40;\r
-                               break;\r
-                       case 0x20:\r
-                               // text, normal\r
-                               draw_text_normal(src);\r
-                               break;\r
-                       case 0x80:\r
-                               // fine graph, wide\r
-                               draw_fine_wide(src);\r
-                               break;\r
-                       case 0xa0:\r
-                               // fine graph, normal\r
-                               draw_fine_normal(src);\r
-                               break;\r
-                       }\r
-               }\r
-       }\r
-       \r
-       // copy to real screen\r
-       for(int y = 0; y < 200; y++) {\r
-               scrntype* dest0 = emu->screen_buffer(y * 2 + 0);\r
-               scrntype* dest1 = emu->screen_buffer(y * 2 + 1);\r
-               uint8* src = screen[y];\r
-               \r
-               for(int x = 0; x < 640; x++) {\r
-                       dest0[x] = palette_pc[src[x] & 7];\r
-               }\r
-               if(scanline) {\r
-//                     for(int x = 0; x < 640; x++) {\r
-//                             dest1[x] = palette_pc[0];\r
-//                     }\r
-                       memset(dest1, 0, 640 * sizeof(scrntype));\r
-               } else {\r
-                       memcpy(dest1, dest0, 640 * sizeof(scrntype));\r
-               }\r
-       }\r
-#endif\r
-       emu->screen_skip_line = true;\r
-}\r
-\r
-void DISPLAY::draw_text_normal(uint16 src)\r
-{\r
-       // text mode, normal char (80chars)\r
-       uint16 src_t = (src & 0x3ff8) + text_page;\r
-       int maxx = 79, maxy = 24, hsync_pos = 92, vsync_pos = 28;\r
-       int _maxx = maxx + 36, _minx = -36;\r
-       int homex = hsync_pos - regs[2], homey = vsync_pos - regs[7];\r
-       int endx = regs[1] + homex, endy = regs[6] + homey;\r
-       int _dstx, dstx = homex, dsty = homey;\r
-       \r
-       for(int y = 0; y < 200; y += 8) {\r
-               for(int x = 0; x < 80; x++, dstx++, src = (src + 8) & 0x3ff8, src_t = (src_t + 8) & 0x3fff) {\r
-                       if(dstx >= endx) {\r
-                               dstx = homex;\r
-                               dsty++;\r
-                       }\r
-                       if(dsty >= endy) {\r
-                               // exit x and y loop\r
-                               y = 200;\r
-                               break;\r
-                       }\r
-                       if((dsty < 0)||(dsty > maxy)) {\r
-                               continue;\r
-                       }\r
-                       _dstx = dstx;\r
-                       if((regs[8] & 0x30) == 0x10) {\r
-                               if(dstx == 0) {\r
-                                       _dstx = 1;\r
-                               }\r
-                               if(dstx == 1) {\r
-                                       continue;\r
-                               }\r
-                       }\r
-                       if((regs[8] & 0x30) == 0x20) {\r
-                               if((dstx == 0) || (dstx == 1)) {\r
-                                       continue;\r
-                               }\r
-                       }\r
-                       if(dstx <= _minx) {\r
-                               _dstx = maxx - (dstx - _minx);\r
-                       }\r
-                       if(dstx >= _maxx) {\r
-                               _dstx = dstx - _maxx;\r
-                       }\r
-                       if((_dstx < 0)||(_dstx > maxx)) {\r
-                               continue;\r
-                       }\r
-                       uint8 code = vram_g[src_t];\r
-                       uint8 attr = vram_a[src_t];\r
-                       uint8 c, c_t = (mode & 8) ? (mode & 7) : (attr & 7);\r
-                       uint8* font_base = &font[code << 3];\r
-                       uint8 p = pal_dis ? 0 : 0xff;\r
-                       \r
-                       for(int l = 0; l < 8; l++) {\r
-                               uint8 p1 = vram_b[src + l] & p;\r
-                               uint8 p2 = vram_r[src + l] & p;\r
-                               uint8 p3 = font_base[l];\r
-                               // negative, blink\r
-                               if(attr & 8) {\r
-                                       p3 = ~p3;\r
-                               }\r
-                               if((mode & 8) && !(attr & 4) && blink) {\r
-                                       p3 = 0;\r
-                               }\r
-                               uint8* d = &screen[(dsty << 3) + l][_dstx << 3];\r
-                               \r
-                               c = ((p1 & 0x80) >> 7) | ((p2 & 0x80) >> 6) | 0;\r
-                               d[0] = (pal[c] & 8) ? (pal[c] & 7) : (p3 & 0x80) ? c_t : (pal[c] & 7);\r
-                               c = ((p1 & 0x40) >> 6) | ((p2 & 0x40) >> 5) | 8;\r
-                               d[1] = (pal[c] & 8) ? (pal[c] & 7) : (p3 & 0x40) ? c_t : (pal[c] & 7);\r
-                               c = ((p1 & 0x20) >> 5) | ((p2 & 0x20) >> 4) | 0;\r
-                               d[2] = (pal[c] & 8) ? (pal[c] & 7) : (p3 & 0x20) ? c_t : (pal[c] & 7);\r
-                               c = ((p1 & 0x10) >> 4) | ((p2 & 0x10) >> 3) | 8;\r
-                               d[3] = (pal[c] & 8) ? (pal[c] & 7) : (p3 & 0x10) ? c_t : (pal[c] & 7);\r
-                               c = ((p1 & 0x08) >> 3) | ((p2 & 0x08) >> 2) | 0;\r
-                               d[4] = (pal[c] & 8) ? (pal[c] & 7) : (p3 & 0x08) ? c_t : (pal[c] & 7);\r
-                               c = ((p1 & 0x04) >> 2) | ((p2 & 0x04) >> 1) | 8;\r
-                               d[5] = (pal[c] & 8) ? (pal[c] & 7) : (p3 & 0x04) ? c_t : (pal[c] & 7);\r
-                               c = ((p1 & 0x02) >> 1) | ((p2 & 0x02) >> 0) | 0;\r
-                               d[6] = (pal[c] & 8) ? (pal[c] & 7) : (p3 & 0x02) ? c_t : (pal[c] & 7);\r
-                               c = ((p1 & 0x01) >> 0) | ((p2 & 0x01) << 1) | 8;\r
-                               d[7] = (pal[c] & 8) ? (pal[c] & 7) : (p3 & 0x01) ? c_t : (pal[c] & 7);\r
-                       }\r
-                       if(src == cursor) {\r
-                               int bp = regs[10] & 0x60;\r
-                               if(bp == 0 || (bp == 0x40 && (cblink & 8)) || (bp == 0x60 && (cblink & 0x10))) {\r
-                                       for(int i = (regs[10] & 7); i < 8; i++) {\r
-                                               memset(&screen[(dsty << 3) + i][_dstx << 3], 7, 8);\r
-                                       }\r
-                               }\r
-                       }\r
-               }\r
-       }\r
-}\r
-\r
-void DISPLAY::draw_text_wide(uint16 src)\r
-{\r
-       // text mode, wide char (40chars)\r
-       uint16 src_t = (src & 0x3ff8) + text_page;\r
-       int maxx = 39, maxy = 24, hsync_pos = 47, vsync_pos = 28;\r
-       int _maxx = maxx + 18, _minx = -18;\r
-       int homex = hsync_pos - regs[2], homey = vsync_pos - regs[7];\r
-       int endx = regs[1] + homex, endy = regs[6] + homey;\r
-       int _dstx, dstx = homex, dsty = homey;\r
-       \r
-       for(int y = 0; y < 200; y += 8) {\r
-               for(int x = 0; x < 40; x++, dstx++, src = (src + 8) & 0x3ff8, src_t = (src_t + 8) & 0x3fff) {\r
-                       if(dstx >= endx) {\r
-                               dstx = homex;\r
-                               dsty++;\r
-                       }\r
-                       if(dsty >= endy) {\r
-                               // exit x and y loop\r
-                               y = 200;\r
-                               break;\r
-                       }\r
-                       if((dsty < 0)||(dsty > maxy)) {\r
-                               continue;\r
-                       }\r
-                       _dstx = dstx;\r
-                       if((regs[8] & 0x30) == 0x10) {\r
-                               if(dstx == 0) {\r
-                                       _dstx = 1;\r
-                               }\r
-                               if(dstx == 1) {\r
-                                       continue;\r
-                               }\r
-                       }\r
-                       if((regs[8] & 0x30) == 0x20) {\r
-                               if((dstx == 0) || (dstx == 1)) {\r
-                                       continue;\r
-                               }\r
-                       }\r
-                       if(dstx <= _minx) {\r
-                               _dstx = maxx - (dstx - _minx);\r
-                       }\r
-                       if(dstx >= _maxx) {\r
-                               _dstx = dstx - _maxx;\r
-                       }\r
-                       if((_dstx < 0)||(_dstx > maxx)) {\r
-                               continue;\r
-                       }\r
-                       \r
-                       uint8 code = vram_g[src_t];\r
-                       uint8 attr = vram_a[src_t];\r
-                       uint8 c, c_t = (mode & 8) ? (mode & 7) : (attr & 7);\r
-                       uint8* font_base = &font[code << 3];\r
-                       uint8 p = pal_dis ? 0 : 0xff;\r
-                       \r
-                       for(int l = 0; l < 8; l++) {\r
-                               uint8 p1 = vram_b[src + l] & p;\r
-                               uint8 p2 = vram_r[src + l] & p;\r
-                               uint8 p3 = font_base[l];\r
-                               // negative, blink\r
-                               if(attr & 8) {\r
-                                       p3 = ~p3;\r
-                               }\r
-                               if((mode & 8) && !(attr & 4) && blink) {\r
-                                       p3 = 0;\r
-                               }\r
-                               uint8* d = &screen[(dsty << 3) + l][_dstx << 4];\r
-                               \r
-                               c = ((p1 & 0x80) >> 7) | ((p2 & 0x80) >> 6);\r
-                               d[ 0] = (pal[c | 0] & 8) ? (pal[c | 0] & 7) : (p3 & 0x80) ? c_t : (pal[c | 0] & 7);\r
-                               d[ 1] = (pal[c | 8] & 8) ? (pal[c | 8] & 7) : (p3 & 0x80) ? c_t : (pal[c | 8] & 7);\r
-                               c = ((p1 & 0x40) >> 6) | ((p2 & 0x40) >> 5);\r
-                               d[ 2] = (pal[c | 0] & 8) ? (pal[c | 0] & 7) : (p3 & 0x40) ? c_t : (pal[c | 0] & 7);\r
-                               d[ 3] = (pal[c | 8] & 8) ? (pal[c | 8] & 7) : (p3 & 0x40) ? c_t : (pal[c | 8] & 7);\r
-                               c = ((p1 & 0x20) >> 5) | ((p2 & 0x20) >> 4);\r
-                               d[ 4] = (pal[c | 0] & 8) ? (pal[c | 0] & 7) : (p3 & 0x20) ? c_t : (pal[c | 0] & 7);\r
-                               d[ 5] = (pal[c | 8] & 8) ? (pal[c | 8] & 7) : (p3 & 0x20) ? c_t : (pal[c | 8] & 7);\r
-                               c = ((p1 & 0x10) >> 4) | ((p2 & 0x10) >> 3);\r
-                               d[ 6] = (pal[c | 0] & 8) ? (pal[c | 0] & 7) : (p3 & 0x10) ? c_t : (pal[c | 0] & 7);\r
-                               d[ 7] = (pal[c | 8] & 8) ? (pal[c | 8] & 7) : (p3 & 0x10) ? c_t : (pal[c | 8] & 7);\r
-                               c = ((p1 & 0x08) >> 3) | ((p2 & 0x08) >> 2);\r
-                               d[ 8] = (pal[c | 0] & 8) ? (pal[c | 0] & 7) : (p3 & 0x08) ? c_t : (pal[c | 0] & 7);\r
-                               d[ 9] = (pal[c | 8] & 8) ? (pal[c | 8] & 7) : (p3 & 0x08) ? c_t : (pal[c | 8] & 7);\r
-                               c = ((p1 & 0x04) >> 2) | ((p2 & 0x04) >> 1);\r
-                               d[10] = (pal[c | 0] & 8) ? (pal[c | 0] & 7) : (p3 & 0x04) ? c_t : (pal[c | 0] & 7);\r
-                               d[11] = (pal[c | 8] & 8) ? (pal[c | 8] & 7) : (p3 & 0x04) ? c_t : (pal[c | 8] & 7);\r
-                               c = ((p1 & 0x02) >> 1) | ((p2 & 0x02) >> 0);\r
-                               d[12] = (pal[c | 0] & 8) ? (pal[c | 0] & 7) : (p3 & 0x02) ? c_t : (pal[c | 0] & 7);\r
-                               d[13] = (pal[c | 8] & 8) ? (pal[c | 8] & 7) : (p3 & 0x02) ? c_t : (pal[c | 8] & 7);\r
-                               c = ((p1 & 0x01) >> 0) | ((p2 & 0x01) << 1);\r
-                               d[14] = (pal[c | 0] & 8) ? (pal[c | 0] & 7) : (p3 & 0x01) ? c_t : (pal[c | 0] & 7);\r
-                               d[15] = (pal[c | 8] & 8) ? (pal[c | 8] & 7) : (p3 & 0x01) ? c_t : (pal[c | 8] & 7);\r
-                       }\r
-                       if(src == cursor) {\r
-                               int bp = regs[10] & 0x60;\r
-                               if(bp == 0 || (bp == 0x40 && (cblink & 8)) || (bp == 0x60 && (cblink & 0x10))) {\r
-                                       for(int i = (regs[10] & 7); i < 8; i++) {\r
-                                               memset(&screen[(dsty << 3) + i][_dstx << 4], 7, 16);\r
-                                       }\r
-                               }\r
-                       }\r
-               }\r
-       }\r
-}\r
-\r
-void DISPLAY::draw_fine_normal(uint16 src)\r
-{\r
-       // fine graph mode, normal char (80chars)\r
-       int maxx = 79, maxy = 24, hsync_pos = 92, vsync_pos = 28;\r
-       int _maxx = maxx + 36, _minx = -36;\r
-       int homex = hsync_pos - regs[2], homey = vsync_pos - regs[7];\r
-       int endx = regs[1] + homex, endy = regs[6] + homey;\r
-       int _dstx, dstx = homex, dsty = homey;\r
-       \r
-       for(int y = 0; y < 200; y += 8) {\r
-               for(int x = 0; x < 80; x++, dstx++, src = (src + 8) & 0x3ff8) {\r
-                       if(dstx >= endx) {\r
-                               dstx = homex;\r
-                               dsty++;\r
-                       }\r
-                       if(dsty >= endy) {\r
-                               // exit x and y loop\r
-                               y = 200;\r
-                               break;\r
-                       }\r
-                       if((dsty < 0)||(dsty > maxy)) {\r
-                               continue;\r
-                       }\r
-                       _dstx = dstx;\r
-                       if((regs[8] & 0x30) == 0x10) {\r
-                               if(dstx == 0) {\r
-                                       _dstx = 1;\r
-                               }\r
-                               if(dstx == 1) {\r
-                                       continue;\r
-                               }\r
-                       }\r
-                       if((regs[8] & 0x30) == 0x20) {\r
-                               if((dstx == 0) || (dstx == 1)) {\r
-                                       continue;\r
-                               }\r
-                       }\r
-                       if(dstx <= _minx) {\r
-                               _dstx = maxx - (dstx - _minx);\r
-                       }\r
-                       if(dstx >= _maxx) {\r
-                               _dstx = dstx - _maxx;\r
-                       }\r
-                       if((_dstx < 0)||(_dstx > maxx)) {\r
-                               continue;\r
-                       }\r
-                       \r
-                       for(int l = 0; l < 8; l++) {\r
-                               uint8 code = vram_g[src + l];\r
-                               uint8 attr = vram_a[src + l];\r
-                               uint8 c, c_t = (mode & 8) ? (mode & 7) : (attr & 7);\r
-                               uint8* font_base = &font[code << 3];\r
-                               uint8 p = pal_dis ? 0 : 0xff;\r
-                               uint8* d = &screen[(dsty << 3) + l][_dstx << 3];\r
-                               \r
-                               if(attr & 8) {\r
-                                       // dot mode\r
-                                       uint8 p1 = vram_b[src + l] & p;\r
-                                       uint8 p2 = vram_r[src + l] & p;\r
-                                       uint8 p3 = vram_g[src + l] & p;\r
-                                       \r
-                                       d[0] = pal[((p1 & 0x80) >> 7) | ((p2 & 0x80) >> 6) | ((p3 & 0x80) >> 5) | 0] & 7;\r
-                                       d[1] = pal[((p1 & 0x40) >> 6) | ((p2 & 0x40) >> 5) | ((p3 & 0x40) >> 4) | 8] & 7;\r
-                                       d[2] = pal[((p1 & 0x20) >> 5) | ((p2 & 0x20) >> 4) | ((p3 & 0x20) >> 3) | 0] & 7;\r
-                                       d[3] = pal[((p1 & 0x10) >> 4) | ((p2 & 0x10) >> 3) | ((p3 & 0x10) >> 2) | 8] & 7;\r
-                                       d[4] = pal[((p1 & 0x08) >> 3) | ((p2 & 0x08) >> 2) | ((p3 & 0x08) >> 1) | 0] & 7;\r
-                                       d[5] = pal[((p1 & 0x04) >> 2) | ((p2 & 0x04) >> 1) | ((p3 & 0x04) >> 0) | 8] & 7;\r
-                                       d[6] = pal[((p1 & 0x02) >> 1) | ((p2 & 0x02) >> 0) | ((p3 & 0x02) << 1) | 0] & 7;\r
-                                       d[7] = pal[((p1 & 0x01) >> 0) | ((p2 & 0x01) << 1) | ((p3 & 0x01) << 2) | 8] & 7;\r
-                               } else {\r
-                                       // text\r
-                                       uint8 p1 = vram_b[src + l] & p;\r
-                                       uint8 p2 = vram_r[src + l] & p;\r
-                                       uint8 p3 = font_base[l];\r
-                                       if(mode & 8) {\r
-                                               // negative, blink\r
-                                               if(attr & 8) {\r
-                                                       p3 = ~p3;\r
-                                               }\r
-                                               if(!(attr & 4) && blink) {\r
-                                                       p3 = 0;\r
-                                               }\r
-                                       }\r
-                                       c = ((p1 & 0x80) >> 7) | ((p2 & 0x80) >> 6) | 0;\r
-                                       d[0] = (pal[c] & 8) ? (pal[c] & 7) : (p3 & 0x80) ? c_t : (pal[c] & 7);\r
-                                       c = ((p1 & 0x40) >> 6) | ((p2 & 0x40) >> 5) | 8;\r
-                                       d[1] = (pal[c] & 8) ? (pal[c] & 7) : (p3 & 0x40) ? c_t : (pal[c] & 7);\r
-                                       c = ((p1 & 0x20) >> 5) | ((p2 & 0x20) >> 4) | 0;\r
-                                       d[2] = (pal[c] & 8) ? (pal[c] & 7) : (p3 & 0x20) ? c_t : (pal[c] & 7);\r
-                                       c = ((p1 & 0x10) >> 4) | ((p2 & 0x10) >> 3) | 8;\r
-                                       d[3] = (pal[c] & 8) ? (pal[c] & 7) : (p3 & 0x10) ? c_t : (pal[c] & 7);\r
-                                       c = ((p1 & 0x08) >> 3) | ((p2 & 0x08) >> 2) | 0;\r
-                                       d[4] = (pal[c] & 8) ? (pal[c] & 7) : (p3 & 0x08) ? c_t : (pal[c] & 7);\r
-                                       c = ((p1 & 0x04) >> 2) | ((p2 & 0x04) >> 1) | 8;\r
-                                       d[5] = (pal[c] & 8) ? (pal[c] & 7) : (p3 & 0x04) ? c_t : (pal[c] & 7);\r
-                                       c = ((p1 & 0x02) >> 1) | ((p2 & 0x02) >> 0) | 0;\r
-                                       d[6] = (pal[c] & 8) ? (pal[c] & 7) : (p3 & 0x02) ? c_t : (pal[c] & 7);\r
-                                       c = ((p1 & 0x01) >> 0) | ((p2 & 0x01) << 1) | 8;\r
-                                       d[7] = (pal[c] & 8) ? (pal[c] & 7) : (p3 & 0x01) ? c_t : (pal[c] & 7);\r
-                               }\r
-                       }\r
-                       if(src == cursor) {\r
-                               int bp = regs[10] & 0x60;\r
-                               if(bp == 0 || (bp == 0x40 && (cblink & 8)) || (bp == 0x60 && (cblink & 0x10))) {\r
-                                       for(int i = (regs[10] & 7); i < 8; i++) {\r
-                                               memset(&screen[(dsty << 3) + i][_dstx << 3], 7, 8);\r
-                                       }\r
-                               }\r
-                       }\r
-               }\r
-       }\r
-}\r
-\r
-void DISPLAY::draw_fine_wide(uint16 src)\r
-{\r
-       // fine graph mode, wide char (40chars)\r
-       int maxx = 39, maxy = 24, hsync_pos = 47, vsync_pos = 28;       //WIDTH 40\r
-       int _maxx = maxx + 18, _minx = -18;     //WIDTH 40\r
-       int homex = hsync_pos - regs[2], homey = vsync_pos - regs[7];\r
-       int endx = regs[1] + homex, endy = regs[6] + homey;\r
-       int _dstx, dstx = homex, dsty = homey;\r
-       \r
-       for(int y = 0; y < 200; y += 8) {\r
-               for(int x = 0; x < 40; x++, dstx++, src = (src + 8) & 0x3ff8) {\r
-                       if(dstx >= endx) {\r
-                               dstx = homex;\r
-                               dsty++;\r
-                       }\r
-                       if(dsty >= endy) {\r
-                               // exit x and y loop\r
-                               y = 200;\r
-                               break;\r
-                       }\r
-                       if((dsty < 0)||(dsty > maxy)) {\r
-                               continue;\r
-                       }\r
-                       _dstx = dstx;\r
-                       if((regs[8] & 0x30) == 0x10) {\r
-                               if(dstx == 0) {\r
-                                       _dstx = 1;\r
-                               }\r
-                               if(dstx == 1) {\r
-                                       continue;\r
-                               }\r
-                       }\r
-                       if((regs[8] & 0x30) == 0x20) {\r
-                               if((dstx == 0) || (dstx == 1)) {\r
-                                       continue;\r
-                               }\r
-                       }\r
-                       if(dstx <= _minx) {\r
-                               _dstx = maxx - (dstx - _minx);\r
-                       }\r
-                       if(dstx >= _maxx) {\r
-                               _dstx = dstx - _maxx;\r
-                       }\r
-                       if((_dstx < 0)||(_dstx > maxx)) {\r
-                               continue;\r
-                       }\r
-                       \r
-                       for(int l = 0; l < 8; l++) {\r
-                               uint8 code = vram_g[src + l];\r
-                               uint8 attr = vram_a[src + l];\r
-                               uint8 c, c_t = (mode & 8) ? (mode & 7) : (attr & 7);\r
-                               uint8* font_base = &font[code << 3];\r
-                               uint8 p = pal_dis ? 0 : 0xff;\r
-                               uint8* d = &screen[(dsty << 3) + l][_dstx << 4];\r
-                               \r
-                               if(attr & 8) {\r
-                                       // dot mode\r
-                                       uint8 p1 = vram_b[src + l] & p;\r
-                                       uint8 p2 = vram_r[src + l] & p;\r
-                                       uint8 p3 = vram_g[src + l] & p;\r
-                                       \r
-                                       d[ 0] = pal[((p1 & 0x80) >> 7) | ((p2 & 0x80) >> 6) | ((p3 & 0x80) >> 5) | 0] & 7;\r
-                                       d[ 1] = pal[((p1 & 0x80) >> 7) | ((p2 & 0x80) >> 6) | ((p3 & 0x80) >> 5) | 8] & 7;\r
-                                       d[ 2] = pal[((p1 & 0x40) >> 6) | ((p2 & 0x40) >> 5) | ((p3 & 0x40) >> 4) | 0] & 7;\r
-                                       d[ 3] = pal[((p1 & 0x40) >> 6) | ((p2 & 0x40) >> 5) | ((p3 & 0x40) >> 4) | 8] & 7;\r
-                                       d[ 4] = pal[((p1 & 0x20) >> 5) | ((p2 & 0x20) >> 4) | ((p3 & 0x20) >> 3) | 0] & 7;\r
-                                       d[ 5] = pal[((p1 & 0x20) >> 5) | ((p2 & 0x20) >> 4) | ((p3 & 0x20) >> 3) | 8] & 7;\r
-                                       d[ 6] = pal[((p1 & 0x10) >> 4) | ((p2 & 0x10) >> 3) | ((p3 & 0x10) >> 2) | 0] & 7;\r
-                                       d[ 7] = pal[((p1 & 0x10) >> 4) | ((p2 & 0x10) >> 3) | ((p3 & 0x10) >> 2) | 8] & 7;\r
-                                       d[ 8] = pal[((p1 & 0x08) >> 3) | ((p2 & 0x08) >> 2) | ((p3 & 0x08) >> 1) | 0] & 7;\r
-                                       d[ 9] = pal[((p1 & 0x08) >> 3) | ((p2 & 0x08) >> 2) | ((p3 & 0x08) >> 1) | 8] & 7;\r
-                                       d[10] = pal[((p1 & 0x04) >> 2) | ((p2 & 0x04) >> 1) | ((p3 & 0x04) >> 0) | 0] & 7;\r
-                                       d[11] = pal[((p1 & 0x04) >> 2) | ((p2 & 0x04) >> 1) | ((p3 & 0x04) >> 0) | 8] & 7;\r
-                                       d[12] = pal[((p1 & 0x02) >> 1) | ((p2 & 0x02) >> 0) | ((p3 & 0x02) << 1) | 0] & 7;\r
-                                       d[13] = pal[((p1 & 0x02) >> 1) | ((p2 & 0x02) >> 0) | ((p3 & 0x02) << 1) | 8] & 7;\r
-                                       d[14] = pal[((p1 & 0x01) >> 0) | ((p2 & 0x01) << 1) | ((p3 & 0x01) << 2) | 0] & 7;\r
-                                       d[15] = pal[((p1 & 0x01) >> 0) | ((p2 & 0x01) << 1) | ((p3 & 0x01) << 2) | 8] & 7;\r
-                               } else {\r
-                                       // text\r
-                                       uint8 p1 = vram_b[src + l] & p;\r
-                                       uint8 p2 = vram_r[src + l] & p;\r
-                                       uint8 p3 = font_base[l];\r
-                                       if(mode & 8) {\r
-                                               // negative, blink\r
-                                               if(attr & 8) {\r
-                                                       p3 = ~p3;\r
-                                               }\r
-                                               if(!(attr & 4) && blink) {\r
-                                                       p3 = 0;\r
-                                               }\r
-                                       }\r
-                                       c = ((p1 & 0x80) >> 7) | ((p2 & 0x80) >> 6);\r
-                                       d[ 0] = (pal[c | 0] & 8) ? (pal[c | 0] & 7) : (p3 & 0x80) ? c_t : (pal[c | 0] & 7);\r
-                                       d[ 1] = (pal[c | 8] & 8) ? (pal[c | 8] & 7) : (p3 & 0x80) ? c_t : (pal[c | 8] & 7);\r
-                                       c = ((p1 & 0x40) >> 6) | ((p2 & 0x40) >> 5);\r
-                                       d[ 2] = (pal[c | 0] & 8) ? (pal[c | 0] & 7) : (p3 & 0x40) ? c_t : (pal[c | 0] & 7);\r
-                                       d[ 3] = (pal[c | 8] & 8) ? (pal[c | 8] & 7) : (p3 & 0x40) ? c_t : (pal[c | 8] & 7);\r
-                                       c = ((p1 & 0x20) >> 5) | ((p2 & 0x20) >> 4);\r
-                                       d[ 4] = (pal[c | 0] & 8) ? (pal[c | 0] & 7) : (p3 & 0x20) ? c_t : (pal[c | 0] & 7);\r
-                                       d[ 5] = (pal[c | 8] & 8) ? (pal[c | 8] & 7) : (p3 & 0x20) ? c_t : (pal[c | 8] & 7);\r
-                                       c = ((p1 & 0x10) >> 4) | ((p2 & 0x10) >> 3);\r
-                                       d[ 6] = (pal[c | 0] & 8) ? (pal[c | 0] & 7) : (p3 & 0x10) ? c_t : (pal[c | 0] & 7);\r
-                                       d[ 7] = (pal[c | 8] & 8) ? (pal[c | 8] & 7) : (p3 & 0x10) ? c_t : (pal[c | 8] & 7);\r
-                                       c = ((p1 & 0x08) >> 3) | ((p2 & 0x08) >> 2);\r
-                                       d[ 8] = (pal[c | 0] & 8) ? (pal[c | 0] & 7) : (p3 & 0x08) ? c_t : (pal[c | 0] & 7);\r
-                                       d[ 9] = (pal[c | 8] & 8) ? (pal[c | 8] & 7) : (p3 & 0x08) ? c_t : (pal[c | 8] & 7);\r
-                                       c = ((p1 & 0x04) >> 2) | ((p2 & 0x04) >> 1);\r
-                                       d[10] = (pal[c | 0] & 8) ? (pal[c | 0] & 7) : (p3 & 0x04) ? c_t : (pal[c | 0] & 7);\r
-                                       d[11] = (pal[c | 8] & 8) ? (pal[c | 8] & 7) : (p3 & 0x04) ? c_t : (pal[c | 8] & 7);\r
-                                       c = ((p1 & 0x02) >> 1) | ((p2 & 0x02) >> 0);\r
-                                       d[12] = (pal[c | 0] & 8) ? (pal[c | 0] & 7) : (p3 & 0x02) ? c_t : (pal[c | 0] & 7);\r
-                                       d[13] = (pal[c | 8] & 8) ? (pal[c | 8] & 7) : (p3 & 0x02) ? c_t : (pal[c | 8] & 7);\r
-                                       c = ((p1 & 0x01) >> 0) | ((p2 & 0x01) << 1);\r
-                                       d[14] = (pal[c | 0] & 8) ? (pal[c | 0] & 7) : (p3 & 0x01) ? c_t : (pal[c | 0] & 7);\r
-                                       d[15] = (pal[c | 8] & 8) ? (pal[c | 8] & 7) : (p3 & 0x01) ? c_t : (pal[c | 8] & 7);\r
-                               }\r
-                       }\r
-                       if(src == cursor) {\r
-                               int bp = regs[10] & 0x60;\r
-                               if(bp == 0 || (bp == 0x40 && (cblink & 8)) || (bp == 0x60 && (cblink & 0x10))) {\r
-                                       for(int i = (regs[10] & 7); i < 8; i++) {\r
-                                               memset(&screen[(dsty << 3) + i][_dstx << 4], 7, 16);\r
-                                       }\r
-                               }\r
-                       }\r
-               }\r
-       }\r
-}\r
-\r
-void DISPLAY::draw_text_lcd(uint16 src)\r
-{\r
-       // text mode, nomarl char (80chars)\r
-       for(int y = 0, yy = 0; y < 64; y += 8, yy++) {\r
-               int src_g = (src + 640 * (yy & 3) + (yy & 4 ? 8 : 0)) & 0x3ff8;\r
-               int src_t = src_g;// + text_page;\r
-               \r
-               for(int x = 0; x < 40; x++) {\r
-                       uint8 code = vram_g[src_t];\r
-                       uint8 attr = vram_a[src_t];\r
-                       uint8 c, c_t = (mode & 8) ? (mode & 7) : (attr & 7);\r
-                       uint8* font_base = &font[code << 3];\r
-                       \r
-                       for(int l = 0; l < 8; l++) {\r
-                               uint8 p1 = vram_b[src_g + l];\r
-                               uint8 p2 = vram_r[src_g + l];\r
-                               uint8 p3 = font_base[l];\r
-                               // negative, blink\r
-                               if(attr & 8) {\r
-                                       p3 = ~p3;\r
-                               }\r
-                               if((mode & 8) && !(attr & 4) && blink) {\r
-                                       p3 = 0;\r
-                               }\r
-                               uint8* d = &screen[y + l][x << 3];\r
-                               \r
-                               c = ((p1 & 0x80) >> 7) | ((p2 & 0x80) >> 6) | 0;\r
-                               d[0] = (pal[c] & 8) ? (pal[c] & 7) : (p3 & 0x80) ? c_t : (pal[c] & 7);\r
-                               c = ((p1 & 0x40) >> 6) | ((p2 & 0x40) >> 5) | 8;\r
-                               d[1] = (pal[c] & 8) ? (pal[c] & 7) : (p3 & 0x40) ? c_t : (pal[c] & 7);\r
-                               c = ((p1 & 0x20) >> 5) | ((p2 & 0x20) >> 4) | 0;\r
-                               d[2] = (pal[c] & 8) ? (pal[c] & 7) : (p3 & 0x20) ? c_t : (pal[c] & 7);\r
-                               c = ((p1 & 0x10) >> 4) | ((p2 & 0x10) >> 3) | 8;\r
-                               d[3] = (pal[c] & 8) ? (pal[c] & 7) : (p3 & 0x10) ? c_t : (pal[c] & 7);\r
-                               c = ((p1 & 0x08) >> 3) | ((p2 & 0x08) >> 2) | 0;\r
-                               d[4] = (pal[c] & 8) ? (pal[c] & 7) : (p3 & 0x08) ? c_t : (pal[c] & 7);\r
-                               c = ((p1 & 0x04) >> 2) | ((p2 & 0x04) >> 1) | 8;\r
-                               d[5] = (pal[c] & 8) ? (pal[c] & 7) : (p3 & 0x04) ? c_t : (pal[c] & 7);\r
-                               c = ((p1 & 0x02) >> 1) | ((p2 & 0x02) >> 0) | 0;\r
-                               d[6] = (pal[c] & 8) ? (pal[c] & 7) : (p3 & 0x02) ? c_t : (pal[c] & 7);\r
-                               c = ((p1 & 0x01) >> 0) | ((p2 & 0x01) << 1) | 8;\r
-                               d[7] = (pal[c] & 8) ? (pal[c] & 7) : (p3 & 0x01) ? c_t : (pal[c] & 7);\r
-                       }\r
-                       if(src_g == cursor) {\r
-                               int bp = regs[10] & 0x60;\r
-                               if(bp == 0 || (bp == 0x40 && (cblink & 8)) || (bp == 0x60 && (cblink & 0x10))) {\r
-                                       for(int i = (regs[10] & 7); i < 8; i++) {\r
-                                               memset(&screen[y + i][x << 3], 7, 8);\r
-                                       }\r
-                               }\r
-                       }\r
-                       src_g = (src_g + 16) & 0x3ff8;\r
-                       src_t = (src_t + 16) & 0x3fff;\r
-               }\r
-       }\r
-}\r
-\r
-void DISPLAY::draw_fine_lcd(uint16 src)\r
-{\r
-       // fine graph mode, normal char (80chars)\r
-       for(int y = 0, yy = 0; y < 64; y += 8, yy++) {\r
-               int src_g = (src + 640 * (yy & 3) + (yy & 4 ? 8 : 0)) & 0x3ff8;\r
-               \r
-               for(int x = 0; x < 80; x++) {\r
-                       uint8 code = vram_g[src_g];\r
-                       uint8 attr = vram_a[src_g];\r
-                       uint8 c, c_t = (mode & 8) ? (mode & 7) : (attr & 7);\r
-                       uint8* font_base = &font[code << 3];\r
-                       \r
-                       if(attr & 8) {\r
-                               // dot mode\r
-                               for(int l = 0; l < 8; l++) {\r
-                                       uint8 p1 = vram_b[src_g + l];\r
-                                       uint8 p2 = vram_r[src_g + l];\r
-                                       uint8 p3 = vram_g[src_g + l];\r
-                                       uint8* d = &screen[y + l][x << 3];\r
-                                       \r
-                                       d[0] = pal[((p1 & 0x80) >> 7) | ((p2 & 0x80) >> 6) | ((p3 & 0x80) >> 5) | 0] & 7;\r
-                                       d[1] = pal[((p1 & 0x40) >> 6) | ((p2 & 0x40) >> 5) | ((p3 & 0x40) >> 4) | 8] & 7;\r
-                                       d[2] = pal[((p1 & 0x20) >> 5) | ((p2 & 0x20) >> 4) | ((p3 & 0x20) >> 3) | 0] & 7;\r
-                                       d[3] = pal[((p1 & 0x10) >> 4) | ((p2 & 0x10) >> 3) | ((p3 & 0x10) >> 2) | 8] & 7;\r
-                                       d[4] = pal[((p1 & 0x08) >> 3) | ((p2 & 0x08) >> 2) | ((p3 & 0x08) >> 1) | 0] & 7;\r
-                                       d[5] = pal[((p1 & 0x04) >> 2) | ((p2 & 0x04) >> 1) | ((p3 & 0x04) >> 0) | 8] & 7;\r
-                                       d[6] = pal[((p1 & 0x02) >> 1) | ((p2 & 0x02) >> 0) | ((p3 & 0x02) << 1) | 0] & 7;\r
-                                       d[7] = pal[((p1 & 0x01) >> 0) | ((p2 & 0x01) << 1) | ((p3 & 0x01) << 2) | 8] & 7;\r
-                               }\r
-                       } else {\r
-                               // text\r
-                               for(int l = 0; l < 8; l++) {\r
-                                       uint8 p1 = vram_b[src_g + l];\r
-                                       uint8 p2 = vram_r[src_g + l];\r
-                                       uint8 p3 = font_base[l];\r
-                                       if(mode & 8) {\r
-                                               // negative, blink\r
-                                               if(attr & 8) {\r
-                                                       p3 = ~p3;\r
-                                               }\r
-                                               if(!(attr & 4) && blink) {\r
-                                                       p3 = 0;\r
-                                               }\r
-                                       }\r
-                                       uint8* d = &screen[y + l][x << 3];\r
-                                       \r
-                                       c = ((p1 & 0x80) >> 7) | ((p2 & 0x80) >> 6) | 0;\r
-                                       d[0] = (pal[c] & 8) ? (pal[c] & 7) : (p3 & 0x80) ? c_t : (pal[c] & 7);\r
-                                       c = ((p1 & 0x40) >> 6) | ((p2 & 0x40) >> 5) | 8;\r
-                                       d[1] = (pal[c] & 8) ? (pal[c] & 7) : (p3 & 0x40) ? c_t : (pal[c] & 7);\r
-                                       c = ((p1 & 0x20) >> 5) | ((p2 & 0x20) >> 4) | 0;\r
-                                       d[2] = (pal[c] & 8) ? (pal[c] & 7) : (p3 & 0x20) ? c_t : (pal[c] & 7);\r
-                                       c = ((p1 & 0x10) >> 4) | ((p2 & 0x10) >> 3) | 8;\r
-                                       d[3] = (pal[c] & 8) ? (pal[c] & 7) : (p3 & 0x10) ? c_t : (pal[c] & 7);\r
-                                       c = ((p1 & 0x08) >> 3) | ((p2 & 0x08) >> 2) | 0;\r
-                                       d[4] = (pal[c] & 8) ? (pal[c] & 7) : (p3 & 0x08) ? c_t : (pal[c] & 7);\r
-                                       c = ((p1 & 0x04) >> 2) | ((p2 & 0x04) >> 1) | 8;\r
-                                       d[5] = (pal[c] & 8) ? (pal[c] & 7) : (p3 & 0x04) ? c_t : (pal[c] & 7);\r
-                                       c = ((p1 & 0x02) >> 1) | ((p2 & 0x02) >> 0) | 0;\r
-                                       d[6] = (pal[c] & 8) ? (pal[c] & 7) : (p3 & 0x02) ? c_t : (pal[c] & 7);\r
-                                       c = ((p1 & 0x01) >> 0) | ((p2 & 0x01) << 1) | 8;\r
-                                       d[7] = (pal[c] & 8) ? (pal[c] & 7) : (p3 & 0x01) ? c_t : (pal[c] & 7);\r
-                               }\r
-                       }\r
-                       if(src_g == cursor) {\r
-                               int bp = regs[10] & 0x60;\r
-                               if(bp == 0 || (bp == 0x40 && (cblink & 8)) || (bp == 0x60 && (cblink & 0x10))) {\r
-                                       for(int i = (regs[10] & 7); i < 8; i++) {\r
-                                               memset(&screen[y + i][x << 3], 7, 8);\r
-                                       }\r
-                               }\r
-                       }\r
-                       src_g = (src_g + 16) & 0x3ff8;\r
-               }\r
-       }\r
-}\r
-\r
+/*
+       TOSHIBA PASOPIA 7 Emulator 'EmuPIA7'
+
+       Author : Takeda.Toshiya
+       Date   : 2007.02.08 -
+
+       [ display ]
+*/
+
+#include "display.h"
+
+void DISPLAY::initialize()
+{
+       // load rom image
+       FILEIO* fio = new FILEIO();
+       if(fio->Fopen(create_local_path(_T("FONT.ROM")), FILEIO_READ_BINARY)) {
+               fio->Fread(font, sizeof(font), 1);
+               fio->Fclose();
+       }
+       delete fio;
+       
+       // create pc palette
+#ifdef _LCD
+       for(int i = 1; i < 8; i++) {
+               palette_pc[i] = RGB_COLOR(48, 56, 16);
+       }
+       palette_pc[0] = RGB_COLOR(160, 168, 160);
+#else
+       for(int i = 0; i < 8; i++) {
+               palette_pc[i] = RGB_COLOR((i & 2) ? 255 : 0, (i & 4) ? 255 : 0, (i & 1) ? 255 : 0);
+       }
+#endif
+       
+       // initialize
+       for(int i = 0; i < 16; i++) {
+               pal[i] = i & 7;
+       }
+       mode = text_page = 0;
+       cblink = flash_cnt = 0;
+       blink = pal_dis = false;
+       
+       // register event
+       register_frame_event(this);
+}
+
+void DISPLAY::write_signal(int id, uint32_t data, uint32_t mask)
+{
+       if(id == SIG_DISPLAY_I8255_0_A) {
+               mode = data;
+       } else if(id == SIG_DISPLAY_I8255_1_B) {
+               text_page = (data >> 4) & 7;
+       } else if(id == SIG_DISPLAY_I8255_1_C) {
+               blink = ((data & 0x20) != 0);
+               pal_dis = ((data & 8) != 0);
+       }
+}
+
+void DISPLAY::event_frame()
+{
+       cblink = (cblink + 1) & 0x1f;
+}
+
+void DISPLAY::draw_screen()
+{
+       // clear screen buffer
+       memset(screen, 0, sizeof(screen));
+       
+#ifdef _LCD
+       if((regs[8] & 0x30) != 0x30) {
+               // render screen
+               uint16_t src = ((regs[12] << 11) | (regs[13] << 3)) & 0x3ff8;
+               if((regs[8] & 0xc0) == 0xc0) {
+                       cursor = -1;
+               } else {
+                       cursor = ((regs[14] << 11) | (regs[15] << 3)) & 0x3ff8;
+               }
+               
+               switch(mode & 0xa0) {
+               case 0x00:      // text, wide
+               case 0x20:      // text, normal
+                       draw_text_lcd(src);
+                       break;
+               case 0x80:      // fine graph, wide
+               case 0xa0:      // fine graph, normal
+                       draw_fine_lcd(src);
+                       break;
+               }
+       }
+       
+       // copy to real screen
+       emu->set_vm_screen_lines(64);
+       for(int y = 0; y < 64; y++) {
+               scrntype_t* dest0 = emu->get_screen_buffer(y * 2 + 0);
+               scrntype_t* dest1 = emu->get_screen_buffer(y * 2 + 1);
+               uint8_t* src = screen[y];
+               
+               for(int x = 0; x < 320; x++) {
+                       dest0[x] = palette_pc[src[x] & 7];
+               }
+               if(config.scan_line) {
+                       for(int x = 0; x < 320; x++) {
+                               dest1[x] = palette_pc[0];
+                       }
+               } else {
+                       memcpy(dest1, dest0, 320 * sizeof(scrntype_t));
+               }
+       }
+#else
+       if((regs[8] & 0x30) != 0x30) {
+               // sync check
+               uint16_t flash = 0;
+               if(mode & 0x20) {
+                       if(regs[0] < 106 || 118 < regs[0] || 113 < regs[2]) {
+                               flash = 0xffff;
+                       }
+                       flash_cnt -= 320;
+               } else {
+                       if(regs[0] < 53 || 58 < regs[0] || 56 < regs[2]) {
+                               flash = 0xffff;
+                       }
+                       flash_cnt -= 160;
+               }
+               if(regs[4] < 27 || 32 < regs[4] || 16 < regs[5] || 32 < regs[7]) {
+                       flash = 0xffff;
+               }
+               if((regs[8] & 3) == 3 || (regs[9] != 7 && regs[9] != 6)) {
+                       flash = 0xffff;
+               }
+               uint16_t src = (((regs[12] << 11) | (regs[13] << 3)) + (flash_cnt & flash)) & 0x3ff8;
+               if((regs[8] & 0xc0) == 0xc0) {
+                       cursor = -1;
+               } else {
+                       cursor = ((regs[14] << 11) | (regs[15] << 3)) & 0x3ff8;
+               }
+               
+               // render screen
+               if((flash != 0) || (regs[8] & 0x30) != 0x30) {
+                       switch(mode & 0xa0) {
+                       case 0x00:
+                               // text, wide
+                               draw_text_wide(src);
+                               flash_cnt += 40;
+                               break;
+                       case 0x20:
+                               // text, normal
+                               draw_text_normal(src);
+                               break;
+                       case 0x80:
+                               // fine graph, wide
+                               draw_fine_wide(src);
+                               break;
+                       case 0xa0:
+                               // fine graph, normal
+                               draw_fine_normal(src);
+                               break;
+                       }
+               }
+       }
+       
+       // copy to real screen
+       emu->set_vm_screen_lines(200);
+       for(int y = 0; y < 200; y++) {
+               scrntype_t* dest0 = emu->get_screen_buffer(y * 2 + 0);
+               scrntype_t* dest1 = emu->get_screen_buffer(y * 2 + 1);
+               uint8_t* src = screen[y];
+               
+               for(int x = 0; x < 640; x++) {
+                       dest0[x] = palette_pc[src[x] & 7];
+               }
+               if(config.scan_line) {
+//                     for(int x = 0; x < 640; x++) {
+//                             dest1[x] = palette_pc[0];
+//                     }
+                       memset(dest1, 0, 640 * sizeof(scrntype_t));
+               } else {
+                       memcpy(dest1, dest0, 640 * sizeof(scrntype_t));
+               }
+       }
+#endif
+       emu->screen_skip_line(true);
+}
+
+void DISPLAY::draw_text_normal(uint16_t src)
+{
+       // text mode, normal char (80chars)
+       uint16_t src_t = (src & 0x3ff8) + text_page;
+       int maxx = 79, maxy = 24, hsync_pos = 92, vsync_pos = 28;
+       int _maxx = maxx + 36, _minx = -36;
+       int homex = hsync_pos - regs[2], homey = vsync_pos - regs[7];
+       int endx = regs[1] + homex, endy = regs[6] + homey;
+       int _dstx, dstx = homex, dsty = homey;
+       
+       for(int y = 0; y < 200; y += 8) {
+               for(int x = 0; x < 80; x++, dstx++, src = (src + 8) & 0x3ff8, src_t = (src_t + 8) & 0x3fff) {
+                       if(dstx >= endx) {
+                               dstx = homex;
+                               dsty++;
+                       }
+                       if(dsty >= endy) {
+                               // exit x and y loop
+                               y = 200;
+                               break;
+                       }
+                       if((dsty < 0)||(dsty > maxy)) {
+                               continue;
+                       }
+                       _dstx = dstx;
+                       if((regs[8] & 0x30) == 0x10) {
+                               if(dstx == 0) {
+                                       _dstx = 1;
+                               }
+                               if(dstx == 1) {
+                                       continue;
+                               }
+                       }
+                       if((regs[8] & 0x30) == 0x20) {
+                               if((dstx == 0) || (dstx == 1)) {
+                                       continue;
+                               }
+                       }
+                       if(dstx <= _minx) {
+                               _dstx = maxx - (dstx - _minx);
+                       }
+                       if(dstx >= _maxx) {
+                               _dstx = dstx - _maxx;
+                       }
+                       if((_dstx < 0)||(_dstx > maxx)) {
+                               continue;
+                       }
+                       uint8_t code = vram_g[src_t];
+                       uint8_t attr = vram_a[src_t];
+                       uint8_t c, c_t = (mode & 8) ? (mode & 7) : (attr & 7);
+                       uint8_t* font_base = &font[code << 3];
+                       uint8_t p = pal_dis ? 0 : 0xff;
+                       
+                       for(int l = 0; l < 8; l++) {
+                               uint8_t p1 = vram_b[src + l] & p;
+                               uint8_t p2 = vram_r[src + l] & p;
+                               uint8_t p3 = font_base[l];
+                               // negative, blink
+                               if(attr & 8) {
+                                       p3 = ~p3;
+                               }
+                               if((mode & 8) && !(attr & 4) && blink) {
+                                       p3 = 0;
+                               }
+                               uint8_t* d = &screen[(dsty << 3) + l][_dstx << 3];
+                               
+                               c = ((p1 & 0x80) >> 7) | ((p2 & 0x80) >> 6) | 0;
+                               d[0] = (pal[c] & 8) ? (pal[c] & 7) : (p3 & 0x80) ? c_t : (pal[c] & 7);
+                               c = ((p1 & 0x40) >> 6) | ((p2 & 0x40) >> 5) | 8;
+                               d[1] = (pal[c] & 8) ? (pal[c] & 7) : (p3 & 0x40) ? c_t : (pal[c] & 7);
+                               c = ((p1 & 0x20) >> 5) | ((p2 & 0x20) >> 4) | 0;
+                               d[2] = (pal[c] & 8) ? (pal[c] & 7) : (p3 & 0x20) ? c_t : (pal[c] & 7);
+                               c = ((p1 & 0x10) >> 4) | ((p2 & 0x10) >> 3) | 8;
+                               d[3] = (pal[c] & 8) ? (pal[c] & 7) : (p3 & 0x10) ? c_t : (pal[c] & 7);
+                               c = ((p1 & 0x08) >> 3) | ((p2 & 0x08) >> 2) | 0;
+                               d[4] = (pal[c] & 8) ? (pal[c] & 7) : (p3 & 0x08) ? c_t : (pal[c] & 7);
+                               c = ((p1 & 0x04) >> 2) | ((p2 & 0x04) >> 1) | 8;
+                               d[5] = (pal[c] & 8) ? (pal[c] & 7) : (p3 & 0x04) ? c_t : (pal[c] & 7);
+                               c = ((p1 & 0x02) >> 1) | ((p2 & 0x02) >> 0) | 0;
+                               d[6] = (pal[c] & 8) ? (pal[c] & 7) : (p3 & 0x02) ? c_t : (pal[c] & 7);
+                               c = ((p1 & 0x01) >> 0) | ((p2 & 0x01) << 1) | 8;
+                               d[7] = (pal[c] & 8) ? (pal[c] & 7) : (p3 & 0x01) ? c_t : (pal[c] & 7);
+                       }
+                       if(src == cursor) {
+                               int bp = regs[10] & 0x60;
+                               if(bp == 0 || (bp == 0x40 && (cblink & 8)) || (bp == 0x60 && (cblink & 0x10))) {
+                                       for(int i = (regs[10] & 7); i < 8; i++) {
+                                               memset(&screen[(dsty << 3) + i][_dstx << 3], 7, 8);
+                                       }
+                               }
+                       }
+               }
+       }
+}
+
+void DISPLAY::draw_text_wide(uint16_t src)
+{
+       // text mode, wide char (40chars)
+       uint16_t src_t = (src & 0x3ff8) + text_page;
+       int maxx = 39, maxy = 24, hsync_pos = 47, vsync_pos = 28;
+       int _maxx = maxx + 18, _minx = -18;
+       int homex = hsync_pos - regs[2], homey = vsync_pos - regs[7];
+       int endx = regs[1] + homex, endy = regs[6] + homey;
+       int _dstx, dstx = homex, dsty = homey;
+       
+       for(int y = 0; y < 200; y += 8) {
+               for(int x = 0; x < 40; x++, dstx++, src = (src + 8) & 0x3ff8, src_t = (src_t + 8) & 0x3fff) {
+                       if(dstx >= endx) {
+                               dstx = homex;
+                               dsty++;
+                       }
+                       if(dsty >= endy) {
+                               // exit x and y loop
+                               y = 200;
+                               break;
+                       }
+                       if((dsty < 0)||(dsty > maxy)) {
+                               continue;
+                       }
+                       _dstx = dstx;
+                       if((regs[8] & 0x30) == 0x10) {
+                               if(dstx == 0) {
+                                       _dstx = 1;
+                               }
+                               if(dstx == 1) {
+                                       continue;
+                               }
+                       }
+                       if((regs[8] & 0x30) == 0x20) {
+                               if((dstx == 0) || (dstx == 1)) {
+                                       continue;
+                               }
+                       }
+                       if(dstx <= _minx) {
+                               _dstx = maxx - (dstx - _minx);
+                       }
+                       if(dstx >= _maxx) {
+                               _dstx = dstx - _maxx;
+                       }
+                       if((_dstx < 0)||(_dstx > maxx)) {
+                               continue;
+                       }
+                       
+                       uint8_t code = vram_g[src_t];
+                       uint8_t attr = vram_a[src_t];
+                       uint8_t c, c_t = (mode & 8) ? (mode & 7) : (attr & 7);
+                       uint8_t* font_base = &font[code << 3];
+                       uint8_t p = pal_dis ? 0 : 0xff;
+                       
+                       for(int l = 0; l < 8; l++) {
+                               uint8_t p1 = vram_b[src + l] & p;
+                               uint8_t p2 = vram_r[src + l] & p;
+                               uint8_t p3 = font_base[l];
+                               // negative, blink
+                               if(attr & 8) {
+                                       p3 = ~p3;
+                               }
+                               if((mode & 8) && !(attr & 4) && blink) {
+                                       p3 = 0;
+                               }
+                               uint8_t* d = &screen[(dsty << 3) + l][_dstx << 4];
+                               
+                               c = ((p1 & 0x80) >> 7) | ((p2 & 0x80) >> 6);
+                               d[ 0] = (pal[c | 0] & 8) ? (pal[c | 0] & 7) : (p3 & 0x80) ? c_t : (pal[c | 0] & 7);
+                               d[ 1] = (pal[c | 8] & 8) ? (pal[c | 8] & 7) : (p3 & 0x80) ? c_t : (pal[c | 8] & 7);
+                               c = ((p1 & 0x40) >> 6) | ((p2 & 0x40) >> 5);
+                               d[ 2] = (pal[c | 0] & 8) ? (pal[c | 0] & 7) : (p3 & 0x40) ? c_t : (pal[c | 0] & 7);
+                               d[ 3] = (pal[c | 8] & 8) ? (pal[c | 8] & 7) : (p3 & 0x40) ? c_t : (pal[c | 8] & 7);
+                               c = ((p1 & 0x20) >> 5) | ((p2 & 0x20) >> 4);
+                               d[ 4] = (pal[c | 0] & 8) ? (pal[c | 0] & 7) : (p3 & 0x20) ? c_t : (pal[c | 0] & 7);
+                               d[ 5] = (pal[c | 8] & 8) ? (pal[c | 8] & 7) : (p3 & 0x20) ? c_t : (pal[c | 8] & 7);
+                               c = ((p1 & 0x10) >> 4) | ((p2 & 0x10) >> 3);
+                               d[ 6] = (pal[c | 0] & 8) ? (pal[c | 0] & 7) : (p3 & 0x10) ? c_t : (pal[c | 0] & 7);
+                               d[ 7] = (pal[c | 8] & 8) ? (pal[c | 8] & 7) : (p3 & 0x10) ? c_t : (pal[c | 8] & 7);
+                               c = ((p1 & 0x08) >> 3) | ((p2 & 0x08) >> 2);
+                               d[ 8] = (pal[c | 0] & 8) ? (pal[c | 0] & 7) : (p3 & 0x08) ? c_t : (pal[c | 0] & 7);
+                               d[ 9] = (pal[c | 8] & 8) ? (pal[c | 8] & 7) : (p3 & 0x08) ? c_t : (pal[c | 8] & 7);
+                               c = ((p1 & 0x04) >> 2) | ((p2 & 0x04) >> 1);
+                               d[10] = (pal[c | 0] & 8) ? (pal[c | 0] & 7) : (p3 & 0x04) ? c_t : (pal[c | 0] & 7);
+                               d[11] = (pal[c | 8] & 8) ? (pal[c | 8] & 7) : (p3 & 0x04) ? c_t : (pal[c | 8] & 7);
+                               c = ((p1 & 0x02) >> 1) | ((p2 & 0x02) >> 0);
+                               d[12] = (pal[c | 0] & 8) ? (pal[c | 0] & 7) : (p3 & 0x02) ? c_t : (pal[c | 0] & 7);
+                               d[13] = (pal[c | 8] & 8) ? (pal[c | 8] & 7) : (p3 & 0x02) ? c_t : (pal[c | 8] & 7);
+                               c = ((p1 & 0x01) >> 0) | ((p2 & 0x01) << 1);
+                               d[14] = (pal[c | 0] & 8) ? (pal[c | 0] & 7) : (p3 & 0x01) ? c_t : (pal[c | 0] & 7);
+                               d[15] = (pal[c | 8] & 8) ? (pal[c | 8] & 7) : (p3 & 0x01) ? c_t : (pal[c | 8] & 7);
+                       }
+                       if(src == cursor) {
+                               int bp = regs[10] & 0x60;
+                               if(bp == 0 || (bp == 0x40 && (cblink & 8)) || (bp == 0x60 && (cblink & 0x10))) {
+                                       for(int i = (regs[10] & 7); i < 8; i++) {
+                                               memset(&screen[(dsty << 3) + i][_dstx << 4], 7, 16);
+                                       }
+                               }
+                       }
+               }
+       }
+}
+
+void DISPLAY::draw_fine_normal(uint16_t src)
+{
+       // fine graph mode, normal char (80chars)
+       int maxx = 79, maxy = 24, hsync_pos = 92, vsync_pos = 28;
+       int _maxx = maxx + 36, _minx = -36;
+       int homex = hsync_pos - regs[2], homey = vsync_pos - regs[7];
+       int endx = regs[1] + homex, endy = regs[6] + homey;
+       int _dstx, dstx = homex, dsty = homey;
+       
+       for(int y = 0; y < 200; y += 8) {
+               for(int x = 0; x < 80; x++, dstx++, src = (src + 8) & 0x3ff8) {
+                       if(dstx >= endx) {
+                               dstx = homex;
+                               dsty++;
+                       }
+                       if(dsty >= endy) {
+                               // exit x and y loop
+                               y = 200;
+                               break;
+                       }
+                       if((dsty < 0)||(dsty > maxy)) {
+                               continue;
+                       }
+                       _dstx = dstx;
+                       if((regs[8] & 0x30) == 0x10) {
+                               if(dstx == 0) {
+                                       _dstx = 1;
+                               }
+                               if(dstx == 1) {
+                                       continue;
+                               }
+                       }
+                       if((regs[8] & 0x30) == 0x20) {
+                               if((dstx == 0) || (dstx == 1)) {
+                                       continue;
+                               }
+                       }
+                       if(dstx <= _minx) {
+                               _dstx = maxx - (dstx - _minx);
+                       }
+                       if(dstx >= _maxx) {
+                               _dstx = dstx - _maxx;
+                       }
+                       if((_dstx < 0)||(_dstx > maxx)) {
+                               continue;
+                       }
+                       
+                       for(int l = 0; l < 8; l++) {
+                               uint8_t code = vram_g[src + l];
+                               uint8_t attr = vram_a[src + l];
+                               uint8_t c, c_t = (mode & 8) ? (mode & 7) : (attr & 7);
+                               uint8_t* font_base = &font[code << 3];
+                               uint8_t p = pal_dis ? 0 : 0xff;
+                               uint8_t* d = &screen[(dsty << 3) + l][_dstx << 3];
+                               
+                               if(attr & 8) {
+                                       // dot mode
+                                       uint8_t p1 = vram_b[src + l] & p;
+                                       uint8_t p2 = vram_r[src + l] & p;
+                                       uint8_t p3 = vram_g[src + l] & p;
+                                       
+                                       d[0] = pal[((p1 & 0x80) >> 7) | ((p2 & 0x80) >> 6) | ((p3 & 0x80) >> 5) | 0] & 7;
+                                       d[1] = pal[((p1 & 0x40) >> 6) | ((p2 & 0x40) >> 5) | ((p3 & 0x40) >> 4) | 8] & 7;
+                                       d[2] = pal[((p1 & 0x20) >> 5) | ((p2 & 0x20) >> 4) | ((p3 & 0x20) >> 3) | 0] & 7;
+                                       d[3] = pal[((p1 & 0x10) >> 4) | ((p2 & 0x10) >> 3) | ((p3 & 0x10) >> 2) | 8] & 7;
+                                       d[4] = pal[((p1 & 0x08) >> 3) | ((p2 & 0x08) >> 2) | ((p3 & 0x08) >> 1) | 0] & 7;
+                                       d[5] = pal[((p1 & 0x04) >> 2) | ((p2 & 0x04) >> 1) | ((p3 & 0x04) >> 0) | 8] & 7;
+                                       d[6] = pal[((p1 & 0x02) >> 1) | ((p2 & 0x02) >> 0) | ((p3 & 0x02) << 1) | 0] & 7;
+                                       d[7] = pal[((p1 & 0x01) >> 0) | ((p2 & 0x01) << 1) | ((p3 & 0x01) << 2) | 8] & 7;
+                               } else {
+                                       // text
+                                       uint8_t p1 = vram_b[src + l] & p;
+                                       uint8_t p2 = vram_r[src + l] & p;
+                                       uint8_t p3 = font_base[l];
+                                       if(mode & 8) {
+                                               // negative, blink
+                                               if(attr & 8) {
+                                                       p3 = ~p3;
+                                               }
+                                               if(!(attr & 4) && blink) {
+                                                       p3 = 0;
+                                               }
+                                       }
+                                       c = ((p1 & 0x80) >> 7) | ((p2 & 0x80) >> 6) | 0;
+                                       d[0] = (pal[c] & 8) ? (pal[c] & 7) : (p3 & 0x80) ? c_t : (pal[c] & 7);
+                                       c = ((p1 & 0x40) >> 6) | ((p2 & 0x40) >> 5) | 8;
+                                       d[1] = (pal[c] & 8) ? (pal[c] & 7) : (p3 & 0x40) ? c_t : (pal[c] & 7);
+                                       c = ((p1 & 0x20) >> 5) | ((p2 & 0x20) >> 4) | 0;
+                                       d[2] = (pal[c] & 8) ? (pal[c] & 7) : (p3 & 0x20) ? c_t : (pal[c] & 7);
+                                       c = ((p1 & 0x10) >> 4) | ((p2 & 0x10) >> 3) | 8;
+                                       d[3] = (pal[c] & 8) ? (pal[c] & 7) : (p3 & 0x10) ? c_t : (pal[c] & 7);
+                                       c = ((p1 & 0x08) >> 3) | ((p2 & 0x08) >> 2) | 0;
+                                       d[4] = (pal[c] & 8) ? (pal[c] & 7) : (p3 & 0x08) ? c_t : (pal[c] & 7);
+                                       c = ((p1 & 0x04) >> 2) | ((p2 & 0x04) >> 1) | 8;
+                                       d[5] = (pal[c] & 8) ? (pal[c] & 7) : (p3 & 0x04) ? c_t : (pal[c] & 7);
+                                       c = ((p1 & 0x02) >> 1) | ((p2 & 0x02) >> 0) | 0;
+                                       d[6] = (pal[c] & 8) ? (pal[c] & 7) : (p3 & 0x02) ? c_t : (pal[c] & 7);
+                                       c = ((p1 & 0x01) >> 0) | ((p2 & 0x01) << 1) | 8;
+                                       d[7] = (pal[c] & 8) ? (pal[c] & 7) : (p3 & 0x01) ? c_t : (pal[c] & 7);
+                               }
+                       }
+                       if(src == cursor) {
+                               int bp = regs[10] & 0x60;
+                               if(bp == 0 || (bp == 0x40 && (cblink & 8)) || (bp == 0x60 && (cblink & 0x10))) {
+                                       for(int i = (regs[10] & 7); i < 8; i++) {
+                                               memset(&screen[(dsty << 3) + i][_dstx << 3], 7, 8);
+                                       }
+                               }
+                       }
+               }
+       }
+}
+
+void DISPLAY::draw_fine_wide(uint16_t src)
+{
+       // fine graph mode, wide char (40chars)
+       int maxx = 39, maxy = 24, hsync_pos = 47, vsync_pos = 28;       //WIDTH 40
+       int _maxx = maxx + 18, _minx = -18;     //WIDTH 40
+       int homex = hsync_pos - regs[2], homey = vsync_pos - regs[7];
+       int endx = regs[1] + homex, endy = regs[6] + homey;
+       int _dstx, dstx = homex, dsty = homey;
+       
+       for(int y = 0; y < 200; y += 8) {
+               for(int x = 0; x < 40; x++, dstx++, src = (src + 8) & 0x3ff8) {
+                       if(dstx >= endx) {
+                               dstx = homex;
+                               dsty++;
+                       }
+                       if(dsty >= endy) {
+                               // exit x and y loop
+                               y = 200;
+                               break;
+                       }
+                       if((dsty < 0)||(dsty > maxy)) {
+                               continue;
+                       }
+                       _dstx = dstx;
+                       if((regs[8] & 0x30) == 0x10) {
+                               if(dstx == 0) {
+                                       _dstx = 1;
+                               }
+                               if(dstx == 1) {
+                                       continue;
+                               }
+                       }
+                       if((regs[8] & 0x30) == 0x20) {
+                               if((dstx == 0) || (dstx == 1)) {
+                                       continue;
+                               }
+                       }
+                       if(dstx <= _minx) {
+                               _dstx = maxx - (dstx - _minx);
+                       }
+                       if(dstx >= _maxx) {
+                               _dstx = dstx - _maxx;
+                       }
+                       if((_dstx < 0)||(_dstx > maxx)) {
+                               continue;
+                       }
+                       
+                       for(int l = 0; l < 8; l++) {
+                               uint8_t code = vram_g[src + l];
+                               uint8_t attr = vram_a[src + l];
+                               uint8_t c, c_t = (mode & 8) ? (mode & 7) : (attr & 7);
+                               uint8_t* font_base = &font[code << 3];
+                               uint8_t p = pal_dis ? 0 : 0xff;
+                               uint8_t* d = &screen[(dsty << 3) + l][_dstx << 4];
+                               
+                               if(attr & 8) {
+                                       // dot mode
+                                       uint8_t p1 = vram_b[src + l] & p;
+                                       uint8_t p2 = vram_r[src + l] & p;
+                                       uint8_t p3 = vram_g[src + l] & p;
+                                       
+                                       d[ 0] = pal[((p1 & 0x80) >> 7) | ((p2 & 0x80) >> 6) | ((p3 & 0x80) >> 5) | 0] & 7;
+                                       d[ 1] = pal[((p1 & 0x80) >> 7) | ((p2 & 0x80) >> 6) | ((p3 & 0x80) >> 5) | 8] & 7;
+                                       d[ 2] = pal[((p1 & 0x40) >> 6) | ((p2 & 0x40) >> 5) | ((p3 & 0x40) >> 4) | 0] & 7;
+                                       d[ 3] = pal[((p1 & 0x40) >> 6) | ((p2 & 0x40) >> 5) | ((p3 & 0x40) >> 4) | 8] & 7;
+                                       d[ 4] = pal[((p1 & 0x20) >> 5) | ((p2 & 0x20) >> 4) | ((p3 & 0x20) >> 3) | 0] & 7;
+                                       d[ 5] = pal[((p1 & 0x20) >> 5) | ((p2 & 0x20) >> 4) | ((p3 & 0x20) >> 3) | 8] & 7;
+                                       d[ 6] = pal[((p1 & 0x10) >> 4) | ((p2 & 0x10) >> 3) | ((p3 & 0x10) >> 2) | 0] & 7;
+                                       d[ 7] = pal[((p1 & 0x10) >> 4) | ((p2 & 0x10) >> 3) | ((p3 & 0x10) >> 2) | 8] & 7;
+                                       d[ 8] = pal[((p1 & 0x08) >> 3) | ((p2 & 0x08) >> 2) | ((p3 & 0x08) >> 1) | 0] & 7;
+                                       d[ 9] = pal[((p1 & 0x08) >> 3) | ((p2 & 0x08) >> 2) | ((p3 & 0x08) >> 1) | 8] & 7;
+                                       d[10] = pal[((p1 & 0x04) >> 2) | ((p2 & 0x04) >> 1) | ((p3 & 0x04) >> 0) | 0] & 7;
+                                       d[11] = pal[((p1 & 0x04) >> 2) | ((p2 & 0x04) >> 1) | ((p3 & 0x04) >> 0) | 8] & 7;
+                                       d[12] = pal[((p1 & 0x02) >> 1) | ((p2 & 0x02) >> 0) | ((p3 & 0x02) << 1) | 0] & 7;
+                                       d[13] = pal[((p1 & 0x02) >> 1) | ((p2 & 0x02) >> 0) | ((p3 & 0x02) << 1) | 8] & 7;
+                                       d[14] = pal[((p1 & 0x01) >> 0) | ((p2 & 0x01) << 1) | ((p3 & 0x01) << 2) | 0] & 7;
+                                       d[15] = pal[((p1 & 0x01) >> 0) | ((p2 & 0x01) << 1) | ((p3 & 0x01) << 2) | 8] & 7;
+                               } else {
+                                       // text
+                                       uint8_t p1 = vram_b[src + l] & p;
+                                       uint8_t p2 = vram_r[src + l] & p;
+                                       uint8_t p3 = font_base[l];
+                                       if(mode & 8) {
+                                               // negative, blink
+                                               if(attr & 8) {
+                                                       p3 = ~p3;
+                                               }
+                                               if(!(attr & 4) && blink) {
+                                                       p3 = 0;
+                                               }
+                                       }
+                                       c = ((p1 & 0x80) >> 7) | ((p2 & 0x80) >> 6);
+                                       d[ 0] = (pal[c | 0] & 8) ? (pal[c | 0] & 7) : (p3 & 0x80) ? c_t : (pal[c | 0] & 7);
+                                       d[ 1] = (pal[c | 8] & 8) ? (pal[c | 8] & 7) : (p3 & 0x80) ? c_t : (pal[c | 8] & 7);
+                                       c = ((p1 & 0x40) >> 6) | ((p2 & 0x40) >> 5);
+                                       d[ 2] = (pal[c | 0] & 8) ? (pal[c | 0] & 7) : (p3 & 0x40) ? c_t : (pal[c | 0] & 7);
+                                       d[ 3] = (pal[c | 8] & 8) ? (pal[c | 8] & 7) : (p3 & 0x40) ? c_t : (pal[c | 8] & 7);
+                                       c = ((p1 & 0x20) >> 5) | ((p2 & 0x20) >> 4);
+                                       d[ 4] = (pal[c | 0] & 8) ? (pal[c | 0] & 7) : (p3 & 0x20) ? c_t : (pal[c | 0] & 7);
+                                       d[ 5] = (pal[c | 8] & 8) ? (pal[c | 8] & 7) : (p3 & 0x20) ? c_t : (pal[c | 8] & 7);
+                                       c = ((p1 & 0x10) >> 4) | ((p2 & 0x10) >> 3);
+                                       d[ 6] = (pal[c | 0] & 8) ? (pal[c | 0] & 7) : (p3 & 0x10) ? c_t : (pal[c | 0] & 7);
+                                       d[ 7] = (pal[c | 8] & 8) ? (pal[c | 8] & 7) : (p3 & 0x10) ? c_t : (pal[c | 8] & 7);
+                                       c = ((p1 & 0x08) >> 3) | ((p2 & 0x08) >> 2);
+                                       d[ 8] = (pal[c | 0] & 8) ? (pal[c | 0] & 7) : (p3 & 0x08) ? c_t : (pal[c | 0] & 7);
+                                       d[ 9] = (pal[c | 8] & 8) ? (pal[c | 8] & 7) : (p3 & 0x08) ? c_t : (pal[c | 8] & 7);
+                                       c = ((p1 & 0x04) >> 2) | ((p2 & 0x04) >> 1);
+                                       d[10] = (pal[c | 0] & 8) ? (pal[c | 0] & 7) : (p3 & 0x04) ? c_t : (pal[c | 0] & 7);
+                                       d[11] = (pal[c | 8] & 8) ? (pal[c | 8] & 7) : (p3 & 0x04) ? c_t : (pal[c | 8] & 7);
+                                       c = ((p1 & 0x02) >> 1) | ((p2 & 0x02) >> 0);
+                                       d[12] = (pal[c | 0] & 8) ? (pal[c | 0] & 7) : (p3 & 0x02) ? c_t : (pal[c | 0] & 7);
+                                       d[13] = (pal[c | 8] & 8) ? (pal[c | 8] & 7) : (p3 & 0x02) ? c_t : (pal[c | 8] & 7);
+                                       c = ((p1 & 0x01) >> 0) | ((p2 & 0x01) << 1);
+                                       d[14] = (pal[c | 0] & 8) ? (pal[c | 0] & 7) : (p3 & 0x01) ? c_t : (pal[c | 0] & 7);
+                                       d[15] = (pal[c | 8] & 8) ? (pal[c | 8] & 7) : (p3 & 0x01) ? c_t : (pal[c | 8] & 7);
+                               }
+                       }
+                       if(src == cursor) {
+                               int bp = regs[10] & 0x60;
+                               if(bp == 0 || (bp == 0x40 && (cblink & 8)) || (bp == 0x60 && (cblink & 0x10))) {
+                                       for(int i = (regs[10] & 7); i < 8; i++) {
+                                               memset(&screen[(dsty << 3) + i][_dstx << 4], 7, 16);
+                                       }
+                               }
+                       }
+               }
+       }
+}
+
+void DISPLAY::draw_text_lcd(uint16_t src)
+{
+       // text mode, nomarl char (80chars)
+       for(int y = 0, yy = 0; y < 64; y += 8, yy++) {
+               int src_g = (src + 640 * (yy & 3) + (yy & 4 ? 8 : 0)) & 0x3ff8;
+               int src_t = src_g;// + text_page;
+               
+               for(int x = 0; x < 40; x++) {
+                       uint8_t code = vram_g[src_t];
+                       uint8_t attr = vram_a[src_t];
+                       uint8_t c, c_t = (mode & 8) ? (mode & 7) : (attr & 7);
+                       uint8_t* font_base = &font[code << 3];
+                       
+                       for(int l = 0; l < 8; l++) {
+                               uint8_t p1 = vram_b[src_g + l];
+                               uint8_t p2 = vram_r[src_g + l];
+                               uint8_t p3 = font_base[l];
+                               // negative, blink
+                               if(attr & 8) {
+                                       p3 = ~p3;
+                               }
+                               if((mode & 8) && !(attr & 4) && blink) {
+                                       p3 = 0;
+                               }
+                               uint8_t* d = &screen[y + l][x << 3];
+                               
+                               c = ((p1 & 0x80) >> 7) | ((p2 & 0x80) >> 6) | 0;
+                               d[0] = (pal[c] & 8) ? (pal[c] & 7) : (p3 & 0x80) ? c_t : (pal[c] & 7);
+                               c = ((p1 & 0x40) >> 6) | ((p2 & 0x40) >> 5) | 8;
+                               d[1] = (pal[c] & 8) ? (pal[c] & 7) : (p3 & 0x40) ? c_t : (pal[c] & 7);
+                               c = ((p1 & 0x20) >> 5) | ((p2 & 0x20) >> 4) | 0;
+                               d[2] = (pal[c] & 8) ? (pal[c] & 7) : (p3 & 0x20) ? c_t : (pal[c] & 7);
+                               c = ((p1 & 0x10) >> 4) | ((p2 & 0x10) >> 3) | 8;
+                               d[3] = (pal[c] & 8) ? (pal[c] & 7) : (p3 & 0x10) ? c_t : (pal[c] & 7);
+                               c = ((p1 & 0x08) >> 3) | ((p2 & 0x08) >> 2) | 0;
+                               d[4] = (pal[c] & 8) ? (pal[c] & 7) : (p3 & 0x08) ? c_t : (pal[c] & 7);
+                               c = ((p1 & 0x04) >> 2) | ((p2 & 0x04) >> 1) | 8;
+                               d[5] = (pal[c] & 8) ? (pal[c] & 7) : (p3 & 0x04) ? c_t : (pal[c] & 7);
+                               c = ((p1 & 0x02) >> 1) | ((p2 & 0x02) >> 0) | 0;
+                               d[6] = (pal[c] & 8) ? (pal[c] & 7) : (p3 & 0x02) ? c_t : (pal[c] & 7);
+                               c = ((p1 & 0x01) >> 0) | ((p2 & 0x01) << 1) | 8;
+                               d[7] = (pal[c] & 8) ? (pal[c] & 7) : (p3 & 0x01) ? c_t : (pal[c] & 7);
+                       }
+                       if(src_g == cursor) {
+                               int bp = regs[10] & 0x60;
+                               if(bp == 0 || (bp == 0x40 && (cblink & 8)) || (bp == 0x60 && (cblink & 0x10))) {
+                                       for(int i = (regs[10] & 7); i < 8; i++) {
+                                               memset(&screen[y + i][x << 3], 7, 8);
+                                       }
+                               }
+                       }
+                       src_g = (src_g + 16) & 0x3ff8;
+                       src_t = (src_t + 16) & 0x3fff;
+               }
+       }
+}
+
+void DISPLAY::draw_fine_lcd(uint16_t src)
+{
+       // fine graph mode, normal char (80chars)
+       for(int y = 0, yy = 0; y < 64; y += 8, yy++) {
+               int src_g = (src + 640 * (yy & 3) + (yy & 4 ? 8 : 0)) & 0x3ff8;
+               
+               for(int x = 0; x < 80; x++) {
+                       uint8_t code = vram_g[src_g];
+                       uint8_t attr = vram_a[src_g];
+                       uint8_t c, c_t = (mode & 8) ? (mode & 7) : (attr & 7);
+                       uint8_t* font_base = &font[code << 3];
+                       
+                       if(attr & 8) {
+                               // dot mode
+                               for(int l = 0; l < 8; l++) {
+                                       uint8_t p1 = vram_b[src_g + l];
+                                       uint8_t p2 = vram_r[src_g + l];
+                                       uint8_t p3 = vram_g[src_g + l];
+                                       uint8_t* d = &screen[y + l][x << 3];
+                                       
+                                       d[0] = pal[((p1 & 0x80) >> 7) | ((p2 & 0x80) >> 6) | ((p3 & 0x80) >> 5) | 0] & 7;
+                                       d[1] = pal[((p1 & 0x40) >> 6) | ((p2 & 0x40) >> 5) | ((p3 & 0x40) >> 4) | 8] & 7;
+                                       d[2] = pal[((p1 & 0x20) >> 5) | ((p2 & 0x20) >> 4) | ((p3 & 0x20) >> 3) | 0] & 7;
+                                       d[3] = pal[((p1 & 0x10) >> 4) | ((p2 & 0x10) >> 3) | ((p3 & 0x10) >> 2) | 8] & 7;
+                                       d[4] = pal[((p1 & 0x08) >> 3) | ((p2 & 0x08) >> 2) | ((p3 & 0x08) >> 1) | 0] & 7;
+                                       d[5] = pal[((p1 & 0x04) >> 2) | ((p2 & 0x04) >> 1) | ((p3 & 0x04) >> 0) | 8] & 7;
+                                       d[6] = pal[((p1 & 0x02) >> 1) | ((p2 & 0x02) >> 0) | ((p3 & 0x02) << 1) | 0] & 7;
+                                       d[7] = pal[((p1 & 0x01) >> 0) | ((p2 & 0x01) << 1) | ((p3 & 0x01) << 2) | 8] & 7;
+                               }
+                       } else {
+                               // text
+                               for(int l = 0; l < 8; l++) {
+                                       uint8_t p1 = vram_b[src_g + l];
+                                       uint8_t p2 = vram_r[src_g + l];
+                                       uint8_t p3 = font_base[l];
+                                       if(mode & 8) {
+                                               // negative, blink
+                                               if(attr & 8) {
+                                                       p3 = ~p3;
+                                               }
+                                               if(!(attr & 4) && blink) {
+                                                       p3 = 0;
+                                               }
+                                       }
+                                       uint8_t* d = &screen[y + l][x << 3];
+                                       
+                                       c = ((p1 & 0x80) >> 7) | ((p2 & 0x80) >> 6) | 0;
+                                       d[0] = (pal[c] & 8) ? (pal[c] & 7) : (p3 & 0x80) ? c_t : (pal[c] & 7);
+                                       c = ((p1 & 0x40) >> 6) | ((p2 & 0x40) >> 5) | 8;
+                                       d[1] = (pal[c] & 8) ? (pal[c] & 7) : (p3 & 0x40) ? c_t : (pal[c] & 7);
+                                       c = ((p1 & 0x20) >> 5) | ((p2 & 0x20) >> 4) | 0;
+                                       d[2] = (pal[c] & 8) ? (pal[c] & 7) : (p3 & 0x20) ? c_t : (pal[c] & 7);
+                                       c = ((p1 & 0x10) >> 4) | ((p2 & 0x10) >> 3) | 8;
+                                       d[3] = (pal[c] & 8) ? (pal[c] & 7) : (p3 & 0x10) ? c_t : (pal[c] & 7);
+                                       c = ((p1 & 0x08) >> 3) | ((p2 & 0x08) >> 2) | 0;
+                                       d[4] = (pal[c] & 8) ? (pal[c] & 7) : (p3 & 0x08) ? c_t : (pal[c] & 7);
+                                       c = ((p1 & 0x04) >> 2) | ((p2 & 0x04) >> 1) | 8;
+                                       d[5] = (pal[c] & 8) ? (pal[c] & 7) : (p3 & 0x04) ? c_t : (pal[c] & 7);
+                                       c = ((p1 & 0x02) >> 1) | ((p2 & 0x02) >> 0) | 0;
+                                       d[6] = (pal[c] & 8) ? (pal[c] & 7) : (p3 & 0x02) ? c_t : (pal[c] & 7);
+                                       c = ((p1 & 0x01) >> 0) | ((p2 & 0x01) << 1) | 8;
+                                       d[7] = (pal[c] & 8) ? (pal[c] & 7) : (p3 & 0x01) ? c_t : (pal[c] & 7);
+                               }
+                       }
+                       if(src_g == cursor) {
+                               int bp = regs[10] & 0x60;
+                               if(bp == 0 || (bp == 0x40 && (cblink & 8)) || (bp == 0x60 && (cblink & 0x10))) {
+                                       for(int i = (regs[10] & 7); i < 8; i++) {
+                                               memset(&screen[y + i][x << 3], 7, 8);
+                                       }
+                               }
+                       }
+                       src_g = (src_g + 16) & 0x3ff8;
+               }
+       }
+}
+
+#define STATE_VERSION  1
+
+bool DISPLAY::process_state(FILEIO* state_fio, bool loading)
+{
+       if(!state_fio->StateCheckUint32(STATE_VERSION)) {
+               return false;
+       }
+       if(!state_fio->StateCheckInt32(this_device_id)) {
+               return false;
+       }
+       state_fio->StateUint8(mode);
+       state_fio->StateUint8(text_page);
+       state_fio->StateUint16(cursor);
+       state_fio->StateUint16(cblink);
+       state_fio->StateUint16(flash_cnt);
+       state_fio->StateBool(blink);
+       state_fio->StateBool(pal_dis);
+       return true;
+}