OSDN Git Service

[VM][WIP] Pre-process to apply new state framework.Still not buildable.
[csp-qt/common_source_project-fm7.git] / source / src / vm / yis / display.cpp
1 /*
2         YAMAHA YIS Emulator 'eYIS'
3
4         Author : Takeda.Toshiya
5         Date   : 2017.04.20-
6
7         [ display ]
8 */
9
10 #include <math.h>
11 #include "display.h"
12 #include "../../fifo.h"
13
14 #ifndef M_PI
15 #define M_PI    3.14159265358979323846
16 #endif
17 #define POW     2
18
19 //              Char    Graph10 Graph20 English
20 // PU-1-10      O       X       X       X
21 // PU-1-20      O       X       O       O
22 // PU-10        O       O       X       X
23
24 static const struct {
25         int length;
26         uint8_t dots[32];
27 } texture_table[8] = {
28         { 1,    {1}},
29         { 4,    {1, 1, 0, 0}},
30         {11,    {1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0}},
31         {16,    {1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0}},
32         { 8,    {1, 1, 1, 1, 0, 0, 0, 0}},
33         {16,    {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0}},
34         {32,    {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0}},
35         {32,    {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0}},
36 };
37
38 static const uint16_t pattern_table[128][16] = {
39         {0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},       // 0
40         {0x7777, 0xffff, 0xffff, 0xffff, 0x7777, 0xffff, 0xffff, 0xffff, 0x7777, 0xffff, 0xffff, 0xffff, 0x7777, 0xffff, 0xffff, 0xffff},
41         {0x7777, 0xffff, 0xdddd, 0xffff, 0x7777, 0xffff, 0xdddd, 0xffff, 0x7777, 0xffff, 0xdddd, 0xffff, 0x7777, 0xffff, 0xdddd, 0xffff},
42         {0x5555, 0xffff, 0xdddd, 0xffff, 0x5555, 0xffff, 0xdddd, 0xffff, 0x5555, 0xffff, 0xdddd, 0xffff, 0x5555, 0xffff, 0xdddd, 0xffff},
43         {0x5555, 0xffff, 0x5555, 0xffff, 0x5555, 0xffff, 0x5555, 0xffff, 0x5555, 0xffff, 0x5555, 0xffff, 0x5555, 0xffff, 0x5555, 0xffff},
44         {0x5555, 0xbbbb, 0x5555, 0xffff, 0x5555, 0xbbbb, 0x5555, 0xffff, 0x5555, 0xbbbb, 0x5555, 0xffff, 0x5555, 0xbbbb, 0x5555, 0xffff},
45         {0x5555, 0xbbbb, 0x5555, 0xeeee, 0x5555, 0xbbbb, 0x5555, 0xeeee, 0x5555, 0xbbbb, 0x5555, 0xeeee, 0x5555, 0xbbbb, 0x5555, 0xeeee},
46         {0x5555, 0xaaaa, 0x5555, 0xeeee, 0x5555, 0xaaaa, 0x5555, 0xeeee, 0x5555, 0xaaaa, 0x5555, 0xeeee, 0x5555, 0xaaaa, 0x5555, 0xeeee},
47         {0x5555, 0xaaaa, 0x5555, 0xaaaa, 0x5555, 0xaaaa, 0x5555, 0xaaaa, 0x5555, 0xaaaa, 0x5555, 0xaaaa, 0x5555, 0xaaaa, 0x5555, 0xaaaa},
48         {0x1111, 0xaaaa, 0x5555, 0xaaaa, 0x1111, 0xaaaa, 0x5555, 0xaaaa, 0x1111, 0xaaaa, 0x5555, 0xaaaa, 0x1111, 0xaaaa, 0x5555, 0xaaaa},
49         {0x1111, 0xaaaa, 0x4444, 0xaaaa, 0x1111, 0xaaaa, 0x4444, 0xaaaa, 0x1111, 0xaaaa, 0x4444, 0xaaaa, 0x1111, 0xaaaa, 0x4444, 0xaaaa},
50         {0x0000, 0xaaaa, 0x4444, 0xaaaa, 0x0000, 0xaaaa, 0x4444, 0xaaaa, 0x0000, 0xaaaa, 0x4444, 0xaaaa, 0x0000, 0xaaaa, 0x4444, 0xaaaa},
51         {0x0000, 0xaaaa, 0x0000, 0xaaaa, 0x0000, 0xaaaa, 0x0000, 0xaaaa, 0x0000, 0xaaaa, 0x0000, 0xaaaa, 0x0000, 0xaaaa, 0x0000, 0xaaaa},
52         {0x0000, 0x2222, 0x0000, 0xaaaa, 0x0000, 0x2222, 0x0000, 0xaaaa, 0x0000, 0x2222, 0x0000, 0xaaaa, 0x0000, 0x2222, 0x0000, 0xaaaa},
53         {0x0000, 0x2222, 0x0000, 0x8888, 0x0000, 0x2222, 0x0000, 0x8888, 0x0000, 0x2222, 0x0000, 0x8888, 0x0000, 0x2222, 0x0000, 0x8888},
54         {0x0000, 0x0000, 0x0000, 0x8888, 0x0000, 0x0000, 0x0000, 0x8888, 0x0000, 0x0000, 0x0000, 0x8888, 0x0000, 0x0000, 0x0000, 0x8888},
55
56         {0xaaaa, 0x0000, 0xaaaa, 0x0000, 0xaaaa, 0x0000, 0xaaaa, 0x0000, 0xaaaa, 0x0000, 0xaaaa, 0x0000, 0xaaaa, 0x0000, 0xaaaa, 0x0000},       // 16
57         {0x5555, 0x0000, 0x5555, 0x0000, 0x5555, 0x0000, 0x5555, 0x0000, 0x5555, 0x0000, 0x5555, 0x0000, 0x5555, 0x0000, 0x5555, 0x0000},
58         {0x0000, 0xaaaa, 0x0000, 0xaaaa, 0x0000, 0xaaaa, 0x0000, 0xaaaa, 0x0000, 0xaaaa, 0x0000, 0xaaaa, 0x0000, 0xaaaa, 0x0000, 0xaaaa},
59         {0x0000, 0x5555, 0x0000, 0x5555, 0x0000, 0x5555, 0x0000, 0x5555, 0x0000, 0x5555, 0x0000, 0x5555, 0x0000, 0x5555, 0x0000, 0x5555},
60         {0xaaaa, 0xaaaa, 0x0000, 0x0000, 0xaaaa, 0xaaaa, 0x0000, 0x0000, 0xaaaa, 0xaaaa, 0x0000, 0x0000, 0xaaaa, 0xaaaa, 0x0000, 0x0000},
61         {0x5555, 0x5555, 0x0000, 0x0000, 0x5555, 0x5555, 0x0000, 0x0000, 0x5555, 0x5555, 0x0000, 0x0000, 0x5555, 0x5555, 0x0000, 0x0000},
62         {0x0000, 0x0000, 0xaaaa, 0xaaaa, 0x0000, 0x0000, 0xaaaa, 0xaaaa, 0x0000, 0x0000, 0xaaaa, 0xaaaa, 0x0000, 0x0000, 0xaaaa, 0xaaaa},
63         {0x0000, 0x0000, 0x5555, 0x5555, 0x0000, 0x0000, 0x5555, 0x5555, 0x0000, 0x0000, 0x5555, 0x5555, 0x0000, 0x0000, 0x5555, 0x5555},
64         {0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
65         {0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
66         {0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
67         {0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
68         {0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
69         {0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
70         {0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
71         {0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
72
73         {0xffff, 0x8888, 0x8888, 0x8888, 0xffff, 0x8888, 0x8888, 0x8888, 0xffff, 0x8888, 0x8888, 0x8888, 0xffff, 0x8888, 0x8888, 0x8888},       // 32
74         {0xffff, 0x8080, 0x8080, 0x8080, 0x8080, 0x8080, 0x8080, 0x8080, 0xffff, 0x8080, 0x8080, 0x8080, 0x8080, 0x8080, 0x8080, 0x8080},
75         {0xffff, 0xffff, 0xc0c0, 0xc0c0, 0xc0c0, 0xc0c0, 0xc0c0, 0xc0c0, 0xffff, 0xffff, 0xc0c0, 0xc0c0, 0xc0c0, 0xc0c0, 0xc0c0, 0xc0c0},
76         {0xffff, 0xc0c0, 0xc0c0, 0xc0c0, 0xffff, 0xc0c0, 0xc0c0, 0xc0c0, 0xffff, 0xc0c0, 0xc0c0, 0xc0c0, 0xffff, 0xc0c0, 0xc0c0, 0xc0c0},
77         {0xffff, 0xffff, 0xffff, 0xffff, 0xf000, 0xf000, 0xf000, 0xf000, 0xf000, 0xf000, 0xf000, 0xf000, 0xf000, 0xf000, 0xf000, 0xf000},
78         {0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
79         {0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
80         {0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
81         {0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
82         {0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
83         {0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
84         {0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
85         {0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
86         {0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
87         {0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
88         {0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
89
90         {0xaaaa, 0x5555, 0xaaaa, 0x5555, 0xaaaa, 0x5555, 0xaaaa, 0x5555, 0xaaaa, 0x5555, 0xaaaa, 0x5555, 0xaaaa, 0x5555, 0xaaaa, 0x5555},       // 48
91         {0xcccc, 0x3333, 0xcccc, 0x3333, 0xcccc, 0x3333, 0xcccc, 0x3333, 0xcccc, 0x3333, 0xcccc, 0x3333, 0xcccc, 0x3333, 0xcccc, 0x3333},
92         {0xaaaa, 0xaaaa, 0x5555, 0x5555, 0xaaaa, 0xaaaa, 0x5555, 0x5555, 0xaaaa, 0xaaaa, 0x5555, 0x5555, 0xaaaa, 0xaaaa, 0x5555, 0x5555},
93         {0xcccc, 0xcccc, 0x3333, 0x3333, 0xcccc, 0xcccc, 0x3333, 0x3333, 0xcccc, 0xcccc, 0x3333, 0x3333, 0xcccc, 0xcccc, 0x3333, 0x3333},
94         {0xcccc, 0xcccc, 0xcccc, 0xcccc, 0x3333, 0x3333, 0x3333, 0x3333, 0xcccc, 0xcccc, 0xcccc, 0xcccc, 0x3333, 0x3333, 0x3333, 0x3333},
95         {0xf0f0, 0xf0f0, 0xf0f0, 0xf0f0, 0x0f0f, 0x0f0f, 0x0f0f, 0x0f0f, 0xf0f0, 0xf0f0, 0xf0f0, 0xf0f0, 0x0f0f, 0x0f0f, 0x0f0f, 0x0f0f},
96         {0xaaaa, 0xaaaa, 0xaaaa, 0xaaaa, 0x5555, 0x5555, 0x5555, 0x5555, 0xaaaa, 0xaaaa, 0xaaaa, 0xaaaa, 0x5555, 0x5555, 0x5555, 0x5555},
97         {0xaaaa, 0xaaaa, 0xaaaa, 0xaaaa, 0xaaaa, 0xaaaa, 0xaaaa, 0xaaaa, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555},
98         {0xcccc, 0xcccc, 0xcccc, 0xcccc, 0xcccc, 0xcccc, 0xcccc, 0xcccc, 0x3333, 0x3333, 0x3333, 0x3333, 0x3333, 0x3333, 0x3333, 0x3333},
99         {0xf0f0, 0xf0f0, 0xf0f0, 0xf0f0, 0xf0f0, 0xf0f0, 0xf0f0, 0xf0f0, 0x0f0f, 0x0f0f, 0x0f0f, 0x0f0f, 0x0f0f, 0x0f0f, 0x0f0f, 0x0f0f},
100         {0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
101         {0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
102         {0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
103         {0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
104         {0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
105         {0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
106
107         {0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000},       // 64
108         {0xaaaa, 0xaaaa, 0xaaaa, 0xaaaa, 0xaaaa, 0xaaaa, 0xaaaa, 0xaaaa, 0xaaaa, 0xaaaa, 0xaaaa, 0xaaaa, 0xaaaa, 0xaaaa, 0xaaaa, 0xaaaa},
109         {0xffff, 0xffff, 0x0000, 0x0000, 0xffff, 0xffff, 0x0000, 0x0000, 0xffff, 0xffff, 0x0000, 0x0000, 0xffff, 0xffff, 0x0000, 0x0000},
110         {0xc0c0, 0xc0c0, 0xc0c0, 0xc0c0, 0xc0c0, 0xc0c0, 0xc0c0, 0xc0c0, 0xc0c0, 0xc0c0, 0xc0c0, 0xc0c0, 0xc0c0, 0xc0c0, 0xc0c0, 0xc0c0},
111         {0xffff, 0xffff, 0xffff, 0xffff, 0x0000, 0x0000, 0x0000, 0x0000, 0xffff, 0xffff, 0xffff, 0xffff, 0x0000, 0x0000, 0x0000, 0x0000},
112         {0xf0f0, 0xf0f0, 0xf0f0, 0xf0f0, 0xf0f0, 0xf0f0, 0xf0f0, 0xf0f0, 0xf0f0, 0xf0f0, 0xf0f0, 0xf0f0, 0xf0f0, 0xf0f0, 0xf0f0, 0xf0f0},
113         {0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000},
114         {0xff00, 0xff00, 0xff00, 0xff00, 0xff00, 0xff00, 0xff00, 0xff00, 0xff00, 0xff00, 0xff00, 0xff00, 0xff00, 0xff00, 0xff00, 0xff00},
115         {0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
116         {0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
117         {0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
118         {0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
119         {0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
120         {0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
121         {0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
122         {0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
123
124         {0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},       // 80
125         {0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
126         {0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
127         {0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
128         {0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
129         {0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
130         {0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
131         {0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
132         {0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
133         {0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
134         {0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
135         {0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
136         {0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
137         {0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
138         {0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
139         {0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
140
141         {0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},       // 96
142         {0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
143         {0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
144         {0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
145         {0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
146         {0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
147         {0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
148         {0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
149         {0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
150         {0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
151         {0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
152         {0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
153         {0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
154         {0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
155         {0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
156         {0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
157
158         {0xffff, 0x8181, 0x8181, 0x9999, 0x9999, 0x8181, 0x8181, 0xffff, 0xffff, 0x8181, 0x8181, 0x9999, 0x9999, 0x8181, 0x8181, 0xffff},       // 112
159         {0xffff, 0x9999, 0x9999, 0x8181, 0x8181, 0x8181, 0x8181, 0xffff, 0xffff, 0x9999, 0x9999, 0x8181, 0x8181, 0x8181, 0x8181, 0xffff},
160         {0xc3c3, 0x9999, 0x9999, 0x8181, 0x8181, 0x9999, 0x9999, 0xc3c3, 0xc3c3, 0x9999, 0x9999, 0x8181, 0x8181, 0x9999, 0x9999, 0xc3c3},
161         {0xffff, 0xc3c3, 0x9999, 0x9999, 0x7e7e, 0x4242, 0x1818, 0x0000, 0xffff, 0xc3c3, 0x9999, 0x9999, 0x7e7e, 0x4242, 0x1818, 0x0000},
162         {0xffff, 0x8080, 0x8c8c, 0x8c8c, 0x8181, 0x8f8f, 0x8f8f, 0x8787, 0xc3c3, 0xe1e1, 0xf0f0, 0xf8f8, 0xf0f0, 0xe1e1, 0xc3c3, 0x8787},
163         {0x1818, 0x3030, 0x6060, 0xc0c0, 0x1818, 0x0c0c, 0x0606, 0x0303, 0x1818, 0x3030, 0x6060, 0xc0c0, 0x1818, 0x0c0c, 0x0606, 0x0303},
164         {0x1818, 0x1818, 0x3030, 0x3030, 0x6060, 0x6060, 0xc0c0, 0xc0c0, 0x1818, 0x1818, 0x0c0c, 0x0c0c, 0x0606, 0x0606, 0x0303, 0x0303},
165         {0x8888, 0x6666, 0x1111, 0x1111, 0x8888, 0x6666, 0x1111, 0x1111, 0x8888, 0x6666, 0x1111, 0x1111, 0x8888, 0x6666, 0x1111, 0x1111},
166         {0x0f0f, 0x0e0e, 0x0c0c, 0x0808, 0xf0f0, 0x7070, 0x3030, 0x1010, 0x0f0f, 0x0e0e, 0x0c0c, 0x0808, 0xf0f0, 0x7070, 0x3030, 0x1010},
167         {0x0f0f, 0x0f0f, 0x0e0e, 0x0e0e, 0x0c0c, 0x0c0c, 0x0808, 0x0808, 0xf0f0, 0xf0f0, 0x7070, 0x7070, 0x3030, 0x3030, 0x1010, 0x1010},
168         {0xfcfc, 0x8c8c, 0xa4a4, 0xf4f4, 0x9f9f, 0xa4a4, 0x8484, 0xfcfc, 0x0303, 0x7373, 0x5b5b, 0x0b0b, 0x6b6b, 0x5b5b, 0x7b7b, 0x0303},
169         {0x0000, 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0x7777, 0x8888, 0x9999, 0xaaaa, 0xbbbb, 0xcccc, 0xdddd, 0xeeee, 0xffff},       // 123 FIXME
170         {0x0000, 0x0000, 0x1111, 0x1111, 0x2222, 0x2222, 0x3333, 0x3333, 0x4444, 0x4444, 0x5555, 0x5555, 0x6666, 0x6666, 0x7777, 0x7777},       // 124 FIXME
171         {0xfe00, 0xfe00, 0xe1c0, 0xe1c0, 0x0e1c, 0x0e1c, 0x01fc, 0x01fc, 0xfe00, 0xfe00, 0xe1c0, 0xe1c0, 0x0e1c, 0x0e1c, 0x01fc, 0x01fc},
172         {0xfe00, 0xfe00, 0xfe00, 0xe000, 0xe1c0, 0xe1c0, 0xe1c0, 0x0e1c, 0x0e1c, 0x0e1c, 0x001c, 0x01fc, 0x01fc, 0x01fc, 0x0000, 0x0000},
173         {0x5555, 0x5555, 0x3333, 0x3333, 0x5555, 0x5555, 0x3333, 0x3333, 0xcccc, 0xcccc, 0xaaaa, 0xaaaa, 0xcccc, 0xcccc, 0xaaaa, 0xaaaa},
174 };
175
176 // KST32B
177 static const uint8_t char_table[256][32] = {
178         {0x00},
179         {0x00},
180         {0x00},
181         {0x00},
182         {0x00},
183         {0x00},
184         {0x00},
185         {0x00},
186         {0x00},
187         {0x00},
188         {0x00},
189         {0x00},
190         {0x00},
191         {0x00},
192         {0x00},
193         {0x00},
194         {0x00},
195         {0x00},
196         {0x00},
197         {0x00},
198         {0x00},
199         {0x00},
200         {0x00},
201         {0x00},
202         {0x00},
203         {0x00},
204         {0x00},
205         {0x00},
206         {0x00},
207         {0x00},
208         {0x00},
209         {0x00},
210         {0x21, 0x7E, 0x00},
211         {0x26, 0xA6, 0x42, 0xC3, 0x45, 0xC6, 0xA9, 0x68, 0xDB, 0x4C, 0x65, 0xC9, 0x00},
212         {0x26, 0xB7, 0xDD, 0x2B, 0xD7, 0x00},
213         {0x21, 0xAB, 0x4E, 0xB5, 0x40, 0x26, 0xBB, 0x61, 0xC4, 0x2B, 0x6D, 0xDB, 0x00},
214         {0x21, 0xA4, 0x4B, 0x6E, 0xC7, 0xCD, 0x6B, 0xD0, 0x44, 0x61, 0xD3, 0xD7, 0x64, 0xDA, 0x4E, 0x2B, 0xBC, 0xC2, 0x28, 0xDC, 0x00},
215         {0x21, 0xB4, 0x62, 0xD1, 0x44, 0x66, 0xD4, 0xD8, 0x64, 0xDB, 0x42, 0x60, 0xD8, 0xD4, 0xA3, 0x6E, 0xDB, 0xAA, 0x6C, 0xCD, 0x4A, 0x68, 0xCA, 0xC6, 0x6A, 0xC3, 0x4C, 0x6E, 0xC6, 0xCA, 0x00},
216         {0x30, 0xA3, 0x6A, 0xC5, 0x67, 0xC9, 0x62, 0xD6, 0xDA, 0x64, 0xDC, 0x47, 0x69, 0xDA, 0xD7, 0x67, 0xD3, 0x62, 0xD0, 0x60, 0xCC, 0xC6, 0x63, 0xC3, 0x46, 0x68, 0xC4, 0x6E, 0xCD, 0x00},
217         {0x28, 0xB6, 0xDC, 0x48, 0x66, 0xD8, 0x00},
218         {0x2D, 0xBC, 0x68, 0xDA, 0x66, 0xD7, 0x65, 0xD3, 0xCB, 0x66, 0xC7, 0x68, 0xC4, 0x6B, 0xC2, 0x00},
219         {0x24, 0xBC, 0x66, 0xDA, 0x68, 0xD7, 0x69, 0xD3, 0xCB, 0x68, 0xC7, 0x66, 0xC4, 0x63, 0xC2, 0x00},
220         {0x21, 0xA9, 0x6E, 0xD6, 0x21, 0x6E, 0xC9, 0x29, 0xA6, 0xD9, 0x00},
221         {0x22, 0xB0, 0x4D, 0x29, 0xB8, 0xC8, 0x00},
222         {0x28, 0xA7, 0x65, 0xC5, 0x64, 0xC7, 0x65, 0xC9, 0x67, 0xC7, 0x66, 0xC4, 0x63, 0xC1, 0x00},
223         {0x22, 0xB0, 0x4D, 0x00},
224         {0x25, 0xA5, 0x66, 0xC3, 0x68, 0xC5, 0x66, 0xC7, 0x64, 0xC5, 0x48, 0x28, 0xA7, 0xC3, 0x00},
225         {0x21, 0xA4, 0x6E, 0xDB, 0x00},
226         {0x21, 0xB5, 0xC9, 0x62, 0xC5, 0x65, 0xC3, 0x48, 0x6B, 0xC5, 0x6D, 0xC9, 0xD5, 0x6B, 0xD9, 0x68, 0xDB, 0x45, 0x62, 0xD9, 0x60, 0xD5, 0x00},
227         {0x24, 0xA3, 0x4B, 0x29, 0xDC, 0x63, 0xD6, 0x00},
228         {0x21, 0xB6, 0x62, 0xD9, 0x65, 0xDB, 0x4A, 0x6C, 0xDA, 0x6E, 0xD7, 0xD3, 0x6C, 0xCE, 0x67, 0xC9, 0x60, 0xC3, 0x4E, 0x00},
229         {0x21, 0xBB, 0x4D, 0x64, 0xD1, 0x49, 0x6C, 0xCF, 0x6D, 0xCD, 0xC7, 0x6C, 0xC5, 0x69, 0xC3, 0x44, 0x62, 0xC4, 0x60, 0xC6, 0x00},
230         {0x2C, 0xA3, 0xDB, 0x29, 0xBC, 0x60, 0xCC, 0xCA, 0x4E, 0x00},
231         {0x21, 0xA6, 0x61, 0xC4, 0x63, 0xC3, 0x49, 0x6B, 0xC4, 0x6D, 0xC7, 0xCE, 0x6C, 0xD0, 0x69, 0xD2, 0x43, 0x60, 0xD0, 0xAF, 0xDB, 0x4D, 0x00},
232         {0x2F, 0xB9, 0x6A, 0xDB, 0x45, 0x62, 0xD9, 0x60, 0xD5, 0xC7, 0x61, 0xC5, 0x64, 0xC3, 0x49, 0x6C, 0xC5, 0x6D, 0xC7, 0xCD, 0x6C, 0xCF, 0x69, 0xD1, 0x44, 0x60, 0xCF, 0x00},
233         {0x21, 0xB7, 0xDB, 0x4E, 0xD9, 0x69, 0xD1, 0x67, 0xCA, 0xC3, 0x00},
234         {0x21, 0xA6, 0xCE, 0x63, 0xD1, 0x4B, 0x6E, 0xCE, 0xC6, 0x6B, 0xC3, 0x43, 0x60, 0xC6, 0x25, 0xB1, 0x61, 0xD4, 0xD8, 0x64, 0xDB, 0x4A, 0x6D, 0xD8, 0xD4, 0x6A, 0xD1, 0x00},
235         {0x21, 0xA5, 0x64, 0xC3, 0x48, 0x6B, 0xC5, 0x6D, 0xC9, 0xD8, 0x6B, 0xDA, 0x69, 0xDB, 0x44, 0x62, 0xDA, 0x60, 0xD8, 0xD0, 0x62, 0xCE, 0x64, 0xCD, 0x4A, 0x6D, 0xD0, 0x00},
236         {0x26, 0xAB, 0x67, 0xCD, 0x69, 0xCB, 0x67, 0xC9, 0x65, 0xCB, 0x49, 0xB4, 0x45, 0x67, 0xD2, 0x69, 0xD4, 0x67, 0xD6, 0x65, 0xD4, 0x00},
237         {0x29, 0xB2, 0x65, 0xD4, 0x67, 0xD6, 0x69, 0xD4, 0x67, 0xD2, 0xD5, 0xA4, 0x69, 0xC7, 0xCB, 0x67, 0xCD, 0x65, 0xCB, 0x67, 0xC9, 0x49, 0x67, 0xCB, 0x00},
238         {0x30, 0xA9, 0x60, 0xD0, 0x6E, 0xD7, 0x00},
239         {0x22, 0xAD, 0x4D, 0xB3, 0x41, 0x00},
240         {0x21, 0xA9, 0x6E, 0xD0, 0x60, 0xD7, 0x00},
241         {0x21, 0xB5, 0xD8, 0x63, 0xDB, 0x4A, 0x6D, 0xD8, 0xD3, 0x6A, 0xD0, 0x67, 0xCC, 0xCA, 0xA6, 0x69, 0xC4, 0x67, 0xC2, 0x65, 0xC4, 0x67, 0xC6, 0xC3, 0x00},
242         {0x2C, 0xA3, 0x44, 0x60, 0xC7, 0xD8, 0x64, 0xDC, 0x4A, 0x6E, 0xD8, 0xC7, 0xB2, 0x6B, 0xD5, 0x48, 0x65, 0xD1, 0xCB, 0x67, 0xC8, 0x4A, 0x6E, 0xCC, 0x00},
243         {0x21, 0xA3, 0x67, 0xDC, 0x6E, 0xC3, 0x24, 0xAC, 0x4B, 0x00},
244         {0x21, 0xA3, 0x4A, 0x6D, 0xC5, 0x6E, 0xC7, 0xCD, 0x6D, 0xCF, 0x69, 0xD1, 0x41, 0xA3, 0xDC, 0x21, 0x49, 0x6C, 0xDA, 0x6D, 0xD8, 0xD5, 0x6C, 0xD3, 0x69, 0xD1, 0x00},
245         {0x30, 0xBC, 0xD6, 0xB8, 0x6A, 0xDC, 0x44, 0x62, 0xDA, 0x60, 0xD6, 0xCA, 0x62, 0xC5, 0x64, 0xC3, 0x4A, 0x6D, 0xC6, 0x6E, 0xC9, 0x00},
246         {0x21, 0xBC, 0x48, 0x6B, 0xDA, 0x6D, 0xD7, 0xC8, 0x6B, 0xC5, 0x68, 0xC3, 0x40, 0x22, 0xDC, 0x00},
247         {0x21, 0xBC, 0x4E, 0xA3, 0x40, 0x22, 0xDC, 0xB1, 0x4C, 0x00},
248         {0x21, 0xBC, 0x4E, 0x22, 0xC3, 0xB0, 0x4B, 0x00},
249         {0x30, 0xB7, 0x6C, 0xDA, 0x69, 0xDC, 0x45, 0x62, 0xDA, 0x60, 0xD7, 0xC8, 0x62, 0xC5, 0x65, 0xC3, 0x4A, 0x6E, 0xC6, 0xCE, 0x4B, 0x00},
250         {0x22, 0xA3, 0xDC, 0x2F, 0xC3, 0xB0, 0x41, 0x00},
251         {0x24, 0xA3, 0x4B, 0x29, 0xDC, 0x24, 0x4B, 0x00},
252         {0x21, 0xA5, 0x63, 0xC2, 0x47, 0x6A, 0xC4, 0x6C, 0xC8, 0xDC, 0x00},
253         {0x22, 0xA3, 0xDC, 0x2F, 0x61, 0xD0, 0x23, 0xB1, 0x6E, 0xC3, 0x00},
254         {0x21, 0xA3, 0x4E, 0x22, 0xDC, 0x00},
255         {0x21, 0xA3, 0x62, 0xDC, 0x67, 0xC9, 0x6C, 0xDC, 0x6E, 0xC3, 0x00},
256         {0x22, 0xA3, 0xDC, 0x6D, 0xC3, 0xDC, 0x00},
257         {0x21, 0xAA, 0x62, 0xC5, 0x64, 0xC3, 0x49, 0x6B, 0xC5, 0x6D, 0xCA, 0xD5, 0x6B, 0xDA, 0x69, 0xDC, 0x44, 0x62, 0xDA, 0x60, 0xD5, 0xCA, 0x00},
258         {0x21, 0xBC, 0x4A, 0x6C, 0xDB, 0x6E, 0xD9, 0xD3, 0x6C, 0xD1, 0x6A, 0xD0, 0x41, 0xBC, 0xC3, 0x00},
259         {0x21, 0xA9, 0xD6, 0x62, 0xDA, 0x65, 0xDC, 0x48, 0x6B, 0xDA, 0x6D, 0xD6, 0xC9, 0x6B, 0xC5, 0x68, 0xC3, 0x45, 0x62, 0xC5, 0x60, 0xC9, 0x25, 0x47, 0x6A, 0xC7, 0x6E, 0xC1, 0x00},
260         {0x21, 0xBC, 0x4A, 0x6C, 0xDB, 0x6E, 0xD8, 0xD4, 0x6C, 0xD1, 0x6A, 0xD0, 0x41, 0x29, 0x6D, 0xC3, 0x4E, 0x22, 0xDC, 0x00},
261         {0x21, 0xA6, 0x62, 0xC3, 0x4A, 0x6D, 0xC6, 0xCC, 0x6A, 0xCF, 0x62, 0xD2, 0x60, 0xD5, 0xD9, 0x63, 0xDC, 0x4A, 0x6D, 0xDA, 0x00},
262         {0x21, 0xBC, 0x4E, 0x29, 0xC3, 0x00},
263         {0x22, 0xBC, 0xC8, 0x62, 0xC5, 0x64, 0xC3, 0x4A, 0x6C, 0xC5, 0x6D, 0xC8, 0xDC, 0x00},
264         {0x21, 0xBC, 0x67, 0xC3, 0x6E, 0xDC, 0x00},
265         {0x21, 0xBC, 0x63, 0xC3, 0x67, 0xD5, 0x6B, 0xC3, 0x6E, 0xDC, 0x00},
266         {0x21, 0xA3, 0x6E, 0xDC, 0x21, 0x6E, 0xC3, 0x00},
267         {0x21, 0xBC, 0x67, 0xD1, 0xC3, 0xB1, 0x6E, 0xDC, 0x00},
268         {0x21, 0xBC, 0x4D, 0x60, 0xC3, 0x4D, 0x00},
269         {0x2E, 0xBC, 0x47, 0xC2, 0x4C, 0x00},
270         {0x21, 0xBB, 0x6E, 0xC4, 0x2A, 0xB0, 0x45, 0x00},
271         {0x23, 0xBC, 0x47, 0xC2, 0x42, 0x00},
272         {0x24, 0xB8, 0x67, 0xDD, 0x6B, 0xD8, 0x00},
273         {0x21, 0xA1, 0x4E, 0x00},
274         {0x2B, 0xB7, 0x68, 0xDD, 0x46, 0x68, 0xDA, 0x00},
275         {0x30, 0xA3, 0x6C, 0xC6, 0xD2, 0x6A, 0xD5, 0x43, 0x60, 0xD3, 0x2E, 0xB0, 0x63, 0xCE, 0x60, 0xCB, 0xC6, 0x63, 0xC3, 0x49, 0x6C, 0xC6, 0x00},
276         {0x22, 0xA3, 0xDC, 0xB1, 0x64, 0xD5, 0x4A, 0x6D, 0xD1, 0xC7, 0x6A, 0xC3, 0x44, 0x61, 0xC7, 0x00},
277         {0x2F, 0xB5, 0xD0, 0xB1, 0x6A, 0xD5, 0x43, 0x60, 0xD1, 0xC7, 0x63, 0xC3, 0x4A, 0x6D, 0xC7, 0x00},
278         {0x2F, 0xBC, 0xC3, 0xA7, 0x6A, 0xC3, 0x43, 0x60, 0xC7, 0xD1, 0x63, 0xD5, 0x4A, 0x6D, 0xD1, 0x00},
279         {0x21, 0xAE, 0x4D, 0xD0, 0x6B, 0xD3, 0x68, 0xD5, 0x45, 0x62, 0xD3, 0x60, 0xD0, 0xC8, 0x62, 0xC5, 0x65, 0xC3, 0x48, 0x6B, 0xC5, 0x6D, 0xC7, 0x00},
280         {0x29, 0xA3, 0xD7, 0x68, 0xDA, 0x6B, 0xDC, 0x4E, 0x2E, 0xB4, 0x42, 0x00},
281         {0x21, 0xA2, 0x63, 0xC0, 0x4A, 0x6D, 0xC3, 0xD5, 0xB2, 0x6A, 0xD5, 0x44, 0x61, 0xD2, 0xCA, 0x64, 0xC7, 0x4A, 0x6D, 0xC9, 0x00},
282         {0x22, 0xA3, 0xDC, 0xB2, 0x64, 0xD5, 0x4A, 0x6D, 0xD2, 0xC3, 0x00},
283         {0x23, 0xA3, 0x4B, 0x29, 0xD5, 0x44, 0xBB, 0x66, 0xD8, 0x68, 0xDB, 0x44, 0x00},
284         {0x21, 0xA3, 0x63, 0xC1, 0x46, 0x69, 0xC3, 0x6B, 0xC7, 0xD4, 0x48, 0xBA, 0x6A, 0xD7, 0x6C, 0xDA, 0x48, 0x00},
285         {0x22, 0xA3, 0xDC, 0xAD, 0x6D, 0xD5, 0xA3, 0x63, 0xCE, 0x00},
286         {0x23, 0xA3, 0x4B, 0x29, 0xDC, 0x44, 0x00},
287         {0x21, 0xA3, 0xD5, 0xB2, 0x62, 0xD5, 0x45, 0x67, 0xD2, 0xC3, 0xB2, 0x69, 0xD5, 0x4C, 0x6E, 0xD2, 0xC3, 0x00},
288         {0x22, 0xA3, 0xD5, 0xB1, 0x64, 0xD5, 0x4A, 0x6D, 0xD1, 0xC3, 0x00},
289         {0x22, 0xB1, 0xC7, 0x62, 0xC5, 0x64, 0xC3, 0x4A, 0x6C, 0xC5, 0x6D, 0xC7, 0xD1, 0x6C, 0xD3, 0x6A, 0xD5, 0x44, 0x62, 0xD3, 0x61, 0xD1, 0x00},
290         {0x22, 0xB5, 0xC0, 0xB2, 0x64, 0xD5, 0x49, 0x6B, 0xD4, 0x6D, 0xD1, 0xCA, 0x6B, 0xC7, 0x69, 0xC6, 0x44, 0x61, 0xC9, 0x00},
291         {0x21, 0xB1, 0xCA, 0x62, 0xC7, 0x64, 0xC6, 0x49, 0x6C, 0xCA, 0x7E, 0xD5, 0xB1, 0x69, 0xD5, 0x44, 0x62, 0xD4, 0x60, 0xD1, 0x00},
292         {0x23, 0xA3, 0xD5, 0xAE, 0x64, 0xD1, 0x66, 0xD3, 0x69, 0xD5, 0x4C, 0x00},
293         {0x2F, 0xB2, 0x6A, 0xD5, 0x44, 0x61, 0xD3, 0xCF, 0x64, 0xCD, 0x4A, 0x6D, 0xCA, 0xC6, 0x6A, 0xC3, 0x43, 0x60, 0xC6, 0x00},
294         {0x22, 0xB5, 0x4D, 0xA3, 0x49, 0x66, 0xC6, 0xD9, 0x00},
295         {0x22, 0xB5, 0xC7, 0x64, 0xC3, 0x49, 0x6D, 0xC8, 0xB5, 0xC3, 0x00},
296         {0x21, 0xB5, 0x67, 0xC3, 0x6E, 0xD5, 0x00},
297         {0x21, 0xB5, 0x64, 0xC3, 0x67, 0xD1, 0x6A, 0xC3, 0x6E, 0xD5, 0x00},
298         {0x22, 0xA3, 0x6D, 0xD5, 0x22, 0x6D, 0xC3, 0x00},
299         {0x22, 0x7E, 0x64, 0xC2, 0x6D, 0xD5, 0x21, 0x66, 0xC6, 0x00},
300         {0x21, 0xB5, 0x4D, 0x60, 0xC3, 0x4D, 0x00},
301         {0x2E, 0xBC, 0x49, 0x66, 0xD9, 0xD0, 0x63, 0xCF, 0x66, 0xCE, 0xC5, 0x69, 0xC2, 0x4C, 0x00},
302         {0x29, 0xA1, 0xDE, 0x00},
303         {0x23, 0xBC, 0x45, 0x68, 0xD9, 0xD0, 0x6B, 0xCF, 0x68, 0xCE, 0xC5, 0x65, 0xC2, 0x42, 0x00},
304         {0x21, 0xB9, 0x63, 0xDC, 0x45, 0x69, 0xD7, 0x4B, 0x6E, 0xDA, 0x00},
305         {0x00},
306         {0x00},
307         {0x00},
308         {0x00},
309         {0x00},
310         {0x00},
311         {0x00},
312         {0x00},
313         {0x00},
314         {0x00},
315         {0x00},
316         {0x00},
317         {0x00},
318         {0x00},
319         {0x00},
320         {0x00},
321         {0x00},
322         {0x00},
323         {0x00},
324         {0x00},
325         {0x00},
326         {0x00},
327         {0x00},
328         {0x00},
329         {0x00},
330         {0x00},
331         {0x00},
332         {0x00},
333         {0x00},
334         {0x00},
335         {0x00},
336         {0x00},
337         {0x00},
338         {0x00},
339         {0x22, 0xA4, 0x63, 0xC2, 0x45, 0x67, 0xC4, 0xC7, 0x65, 0xC9, 0x43, 0x61, 0xC7, 0xC4, 0x00},
340         {0x2A, 0xAB, 0xDD, 0x4D, 0x00},
341         {0x22, 0xA2, 0x46, 0xD4, 0x00},
342         {0x22, 0xAA, 0x64, 0xC7, 0x66, 0xC3, 0x65, 0xC2, 0x63, 0xC4, 0x64, 0xC5, 0x00},
343         {0x29, 0xB2, 0x65, 0xD0, 0x67, 0xCE, 0x69, 0xD0, 0x67, 0xD2, 0xCE, 0x26, 0xB0, 0x49, 0x00},
344         {0x21, 0xBA, 0x4D, 0x6C, 0xD1, 0x6A, 0xCB, 0x67, 0xC6, 0x64, 0xC3, 0x22, 0xB2, 0x4C, 0x00},
345         {0x21, 0xB3, 0x4C, 0x68, 0xCC, 0x29, 0xB1, 0xCE, 0x66, 0xC9, 0x63, 0xC3, 0x00},
346         {0x21, 0xA8, 0x64, 0xCB, 0x68, 0xD0, 0x6B, 0xD6, 0x29, 0xAE, 0xC3, 0x00},
347         {0x21, 0xAE, 0xD2, 0x4B, 0xCD, 0x69, 0xC8, 0x67, 0xC5, 0x64, 0xC3, 0x28, 0xB2, 0xD6, 0x00},
348         {0x21, 0xA5, 0x4C, 0x28, 0xD1, 0x22, 0x4B, 0x00},
349         {0x21, 0xB1, 0x4C, 0x29, 0x63, 0xC9, 0x60, 0xC6, 0x2A, 0xB6, 0xC3, 0x65, 0xC5, 0x00},
350         {0x21, 0xB0, 0x6C, 0xD2, 0x69, 0xCD, 0x25, 0xB6, 0x67, 0xC3, 0x00},
351         {0x21, 0xA5, 0x4C, 0x28, 0x68, 0xC9, 0x69, 0xCD, 0xD1, 0x42, 0x00},
352         {0x21, 0xA4, 0x49, 0x6B, 0xD0, 0xD4, 0x41, 0xAD, 0x4A, 0x00},
353         {0x21, 0xB2, 0x62, 0xCC, 0x28, 0x64, 0xD2, 0xA3, 0x67, 0xC5, 0x6A, 0xCA, 0x6C, 0xD3, 0x00},
354         {0x22, 0xB1, 0x62, 0xD0, 0x4D, 0x00},
355         {0x21, 0xBA, 0x4E, 0x6C, 0xD4, 0x69, 0xCF, 0x2A, 0xB5, 0xCE, 0x67, 0xC9, 0x65, 0xC5, 0x63, 0xC3, 0x00},
356         {0x21, 0xAE, 0x65, 0xD2, 0x69, 0xD7, 0x6C, 0xDD, 0x29, 0xB4, 0xC3, 0x00},
357         {0x21, 0xB2, 0xD7, 0x4E, 0xD2, 0x6C, 0xCA, 0x6A, 0xC6, 0x67, 0xC3, 0xB7, 0xDC, 0x00},
358         {0x21, 0xA5, 0x4E, 0x29, 0xD6, 0x22, 0x4D, 0x00},
359         {0x2C, 0xBC, 0xC3, 0x67, 0xC5, 0x21, 0xA4, 0x64, 0xCA, 0x69, 0xD6, 0x30, 0x40, 0x00},
360         {0x2A, 0xA5, 0x6B, 0xC3, 0x6E, 0xD2, 0xD6, 0x40, 0xA4, 0x64, 0xCA, 0x67, 0xD4, 0xDC, 0x00},
361         {0x30, 0xAE, 0x60, 0xCC, 0xB5, 0x6C, 0xD7, 0x26, 0xBC, 0x69, 0xC3, 0x00},
362         {0x21, 0xB1, 0x62, 0xD7, 0x63, 0xDD, 0x23, 0xB7, 0x4D, 0x6B, 0xCD, 0x68, 0xC6, 0x66, 0xC3, 0x00},
363         {0x21, 0xB0, 0x62, 0xD6, 0x63, 0xDB, 0xDD, 0x23, 0xB6, 0x4E, 0x2C, 0xD2, 0x69, 0xCB, 0x66, 0xC3, 0x00},
364         {0x21, 0xA5, 0x4D, 0xD7, 0x30, 0x41, 0x00},
365         {0x21, 0xB5, 0x4E, 0x2C, 0xBC, 0xCE, 0x69, 0xC9, 0x67, 0xC5, 0x65, 0xC3, 0x24, 0xAF, 0xDB, 0x00},
366         {0x21, 0xB2, 0x66, 0xD0, 0x2A, 0xB6, 0x62, 0xD8, 0x30, 0xB1, 0x6A, 0xC9, 0x66, 0xC5, 0x62, 0xC3, 0x00},
367         {0x2A, 0xAE, 0x6B, 0xC9, 0x6E, 0xC3, 0x21, 0x67, 0xCC, 0x6B, 0xD4, 0x6D, 0xDB, 0x41, 0x00},
368         {0x21, 0xB4, 0x6E, 0xD6, 0x6C, 0xCF, 0x6A, 0xCC, 0x24, 0xBB, 0xCB, 0x64, 0xC8, 0x67, 0xC5, 0x6A, 0xC4, 0x4D, 0x00},
369         {0x21, 0xBA, 0x63, 0xD5, 0x65, 0xD0, 0x24, 0xA3, 0x67, 0xC6, 0x6A, 0xCA, 0x6C, 0xCF, 0x6E, 0xDA, 0x00},
370         {0x23, 0xB2, 0x6B, 0xCF, 0x21, 0x62, 0xD4, 0x64, 0xDD, 0x24, 0xB8, 0x4D, 0xD3, 0x6B, 0xCC, 0x68, 0xC6, 0x65, 0xC3, 0x00},
371         {0x21, 0xB1, 0x4E, 0x2E, 0xBC, 0x66, 0xD9, 0x61, 0xD7, 0x2A, 0xBA, 0xCA, 0x67, 0xC7, 0x65, 0xC5, 0x62, 0xC3, 0x00},
372         {0x21, 0xB8, 0x62, 0xD0, 0x26, 0xBA, 0x67, 0xD2, 0x2F, 0xB9, 0xD2, 0x6B, 0xCA, 0x69, 0xC6, 0x66, 0xC3, 0x00},
373         {0x21, 0xB3, 0x4E, 0x2A, 0xCB, 0x67, 0xC7, 0x65, 0xC4, 0x63, 0xC3, 0x23, 0xBB, 0x4C, 0x00},
374         {0x23, 0xA3, 0xDC, 0xB3, 0x68, 0xCF, 0x6C, 0xCB, 0x00},
375         {0x21, 0xB5, 0x4E, 0x2B, 0xBC, 0xCC, 0x68, 0xC8, 0x66, 0xC5, 0x63, 0xC3, 0x00},
376         {0x21, 0xA6, 0x4E, 0x22, 0xB6, 0x4C, 0x00},
377         {0x21, 0xBA, 0x4D, 0xD7, 0x6C, 0xD2, 0x69, 0xCC, 0x62, 0xC3, 0x24, 0xB4, 0x6E, 0xCB, 0x00},
378         {0x21, 0xA9, 0x64, 0xCB, 0x68, 0xCE, 0x6B, 0xD2, 0x6D, 0xD8, 0x41, 0x29, 0xDC, 0xA3, 0xCD, 0x6E, 0xC9, 0x00},
379         {0x21, 0xA3, 0x66, 0xC7, 0x6A, 0xCC, 0x6D, 0xD3, 0x6E, 0xD8, 0xDB, 0x00},
380         {0x21, 0xA6, 0x63, 0xCC, 0x65, 0xD5, 0x2A, 0xB9, 0x6B, 0xD2, 0x6D, 0xCB, 0x6E, 0xC5, 0x00},
381         {0x22, 0xBC, 0xC8, 0x62, 0xC6, 0x64, 0xC4, 0x67, 0xC3, 0x4E, 0xB7, 0x69, 0xD4, 0x61, 0xD1, 0x00},
382         {0x21, 0xB9, 0x4D, 0xD5, 0x6C, 0xD0, 0x69, 0xCA, 0x66, 0xC6, 0x63, 0xC3, 0x00},
383         {0x21, 0xAF, 0x64, 0xD7, 0x45, 0x6E, 0xC5, 0x00},
384         {0x21, 0xB5, 0x4E, 0xA7, 0x6B, 0xD0, 0x24, 0x60, 0xC7, 0x29, 0xBC, 0xC3, 0x00},
385         {0x21, 0xB7, 0x4E, 0x6C, 0xD0, 0x69, 0xCB, 0x67, 0xC9, 0x24, 0xAE, 0x6B, 0xC3, 0x00},
386         {0x21, 0xA7, 0x68, 0xC5, 0x6E, 0xC3, 0x23, 0xB1, 0x6C, 0xCE, 0xB8, 0x62, 0xDB, 0x00},
387         {0x28, 0xBB, 0xD8, 0x64, 0xCE, 0x60, 0xC6, 0x6C, 0xC9, 0x2D, 0xAE, 0x6E, 0xC3, 0x00},
388         {0x2F, 0xBB, 0xD9, 0x6C, 0xD4, 0x69, 0xCE, 0x65, 0xC8, 0x60, 0xC3, 0x25, 0xB3, 0x68, 0xD1, 0x6E, 0xCD, 0x00},
389         {0x21, 0xB1, 0x4E, 0x2D, 0xBB, 0x66, 0xD9, 0x61, 0xD8, 0x26, 0xCA, 0x66, 0xC7, 0x69, 0xC4, 0x6C, 0xC3, 0x00},
390         {0x21, 0xB4, 0x6E, 0xD6, 0x6C, 0xD2, 0x6A, 0xD0, 0x26, 0xBC, 0x69, 0xC3, 0x00},
391         {0x23, 0xB6, 0x4C, 0xD2, 0x6B, 0xCC, 0x69, 0xC5, 0x21, 0x4E, 0x00},
392         {0x21, 0xBA, 0x4D, 0xD3, 0x6B, 0xC3, 0x40, 0x22, 0xB0, 0x4C, 0x00},
393         {0x21, 0xB5, 0x4D, 0xD2, 0x6C, 0xCC, 0x6A, 0xC8, 0x67, 0xC5, 0x64, 0xC3, 0x22, 0xBB, 0x4C, 0x00},
394         {0x23, 0xAE, 0xDA, 0x2E, 0xBC, 0xCD, 0x6B, 0xC9, 0x69, 0xC5, 0x67, 0xC3, 0x00},
395         {0x21, 0xA5, 0x63, 0xC9, 0x65, 0xCF, 0xD9, 0x2B, 0xBB, 0xC3, 0x6C, 0xC6, 0x6E, 0xCA, 0x00},
396         {0x23, 0xBB, 0xC3, 0x66, 0xC5, 0x6A, 0xC8, 0x6E, 0xCC, 0x00},
397         {0x21, 0xB7, 0x4E, 0x6D, 0xC5, 0x41, 0x60, 0xD7, 0x00},
398         {0x21, 0xB5, 0xDA, 0x4D, 0xD4, 0x6C, 0xCF, 0x69, 0xC9, 0x64, 0xC3, 0x00},
399         {0x21, 0xB8, 0x66, 0xD5, 0x23, 0xA3, 0x65, 0xC6, 0x69, 0xCB, 0x6E, 0xD7, 0x00},
400         {0x21, 0xBA, 0x64, 0xD5, 0xBC, 0x68, 0xD7, 0x00},
401         {0x21, 0xBA, 0xD7, 0x62, 0xD5, 0x44, 0x66, 0xD7, 0xDA, 0x64, 0xDC, 0x42, 0x60, 0xDA, 0x00},
402         {0x00},
403         {0x00},
404         {0x00},
405         {0x00},
406         {0x00},
407         {0x00},
408         {0x00},
409         {0x00},
410         {0x00},
411         {0x00},
412         {0x00},
413         {0x00},
414         {0x00},
415         {0x00},
416         {0x00},
417         {0x00},
418         {0x00},
419         {0x00},
420         {0x00},
421         {0x00},
422         {0x00},
423         {0x00},
424         {0x00},
425         {0x00},
426         {0x00},
427         {0x00},
428         {0x00},
429         {0x00},
430         {0x00},
431         {0x00},
432         {0x00},
433         {0x00},
434 };
435
436 void DISPLAY::initialize()
437 {
438         // load rom image
439         FILEIO* fio = new FILEIO();
440         if(fio->Fopen(create_local_path(_T("FONT.ROM")), FILEIO_READ_BINARY)) {
441                 fio->Fread(font + 0x000, 0x1000, 1);
442                 memcpy(font + 0x1000, font, 0x1000);
443                 fio->Fread(font + 0x1000, 0x1000, 1);
444                 fio->Fclose();
445         }
446         delete fio;
447         
448         // create pc palette
449         for(int i = 0; i < 8; i++) {
450                 palette_text[i]  = RGB_COLOR((i & 1) ? 255 : 0, (i & 2) ? 255 : 0, (i & 4) ? 255 : 0); // text
451                 palette_graph[i] = RGB_COLOR((i & 1) ? 255 : 0, (i & 2) ? 255 : 0, (i & 4) ? 255 : 0); // graph
452         }
453         
454         cmd_buffer = new FIFO(32);
455         dpp_ctrl = 0xff;
456         
457         // register event
458         register_frame_event(this);
459 }
460
461 void DISPLAY::release()
462 {
463         cmd_buffer->release();
464         delete cmd_buffer;
465 }
466
467 void DISPLAY::reset()
468 {
469         switch(monitor_type = config.monitor_type) {
470         case 0: dpp_data = 0x43; break; // PU-1-10
471         case 1: dpp_data = 0x47; break; // PU-1-20
472         case 2: dpp_data = 0x5a; break; // PU-10 ???
473         }
474         for(int y = 0; y < 25; y++) {
475                 for(int x = 0; x < 80; x++) {
476                         cvram[y][x].code = 0x20;
477                         cvram[y][x].attr = 0x0e;
478                 }
479         }
480         memset(gvram, 0, sizeof(gvram));
481         
482         cmd_buffer->clear();
483         active_cmd = -1;
484         
485         // character
486         scroll_x0 = 0;
487         scroll_y0 = 0;
488         scroll_x1 = 79;
489         scroll_y1 = 24;
490         cursor_x = cursor_y = 0;
491         read_x = read_y = 0;
492         mode1 = 0x0e;
493         mode2 = 0x30;
494         mode3 = 0x01;
495         write_cr = false;
496         
497         // graphic
498         window_x0 = view_x0 = -256;
499         window_y0 = view_y0 = -192;
500         window_x1 = view_x1 =  255;
501         window_y1 = view_y1 =  191;
502         expand = 1.0;
503         rotate = 0;
504         translate_x = translate_y = 0;
505         point_x = point_y = 0;
506         fore_color = 7;
507         back_color = 0;
508         erase = false;
509         texture = texture_index = 0;
510         pattern = 0;
511 }
512
513 void DISPLAY::event_frame()
514 {
515         blink = (blink + 1) & 0x1f;
516 }
517
518 void DISPLAY::write_io8(uint32_t addr, uint32_t data)
519 {
520         switch(addr) {
521         case 0xf040: // CAP: WRITE DATA
522         case 0xf048: // GRP: WRITE DATA
523                 if(active_cmd == 0x18) {
524                         emu->force_out_debug_log(_T("Send GPP: %02X\n"), data);
525                         if(data == 0x00) {
526                                 cmd_buffer->clear();
527                                 active_cmd = -1;
528                                 emu->force_out_debug_log(_T("\n"));
529                         } else {
530                                 put_code(data);
531                         }
532                 } else {
533                         if(active_cmd != -1) {
534                                 cmd_buffer->clear();
535                                 active_cmd = -1;
536                                 emu->out_debug_log(_T("\n"));
537                         }
538                         emu->force_out_debug_log(_T("Send GPP: %02X\n"), data);
539                         cmd_buffer->write(data);
540                         process_cmd();
541                 }
542                 break;
543         case 0xf041: // CAP: CONTROL
544         case 0xf049: // GRP: CONTROL
545                 if(!(dpp_ctrl & 1) && (data & 1)) {
546                         // bit0: L->H RESET CAP/GRP
547                         reset();
548                 }
549                 dpp_ctrl = data;
550                 break;
551         }
552 }
553
554 uint32_t DISPLAY::read_io8(uint32_t addr)
555 {
556         switch(addr) {
557         case 0xf041: // CAP: WRITE DATA READY
558         case 0xf049: // GRP: WRITE DATA READY
559                 // bit0: H=READY
560                 return 0x01;
561         case 0xf042: // CAP: READ DATA
562         case 0xf04a: // GRP: READ DATA
563                 if(active_cmd == 0x1a) {
564                         dpp_data = get_code();
565                 } else if(active_cmd == 0x11 || active_cmd == 0x1e) {
566                         dpp_data = report & 0xff;
567                         report >>= 8;
568                 }
569                 emu->out_debug_log(_T("Recv GPP: %02X\n"), dpp_data);
570                 return dpp_data;
571         case 0xf043: // CAP: READ DATA READY
572         case 0xf04b: // GRP: READ DATA READY
573                 // bit0: H=READY
574                 return 0x01;
575         }
576         return 0xff;
577 }
578
579 int get_word(uint8_t flag, uint8_t h, uint8_t l)
580 {
581         pair_t tmp;
582         tmp.b.h = flag ? (h & 0x7f) | ((h & 0x40) << 1) : (h & 0x7f);
583         tmp.b.l = l;
584         return (int)tmp.sw.l;
585 }
586
587 void DISPLAY::process_cmd()
588 {
589         switch(cmd_buffer->read_not_remove(0)) {
590         // CAP
591         case 0x18:
592                 if(cmd_buffer->count() == 1) {
593                         active_cmd = cmd_buffer->read_not_remove(0);
594                 }
595                 break;
596         case 0x19:
597                 if(cmd_buffer->count() == 3) {
598                         cursor_x = cmd_buffer->read_not_remove(1) & 0x7f;
599                         cursor_y = cmd_buffer->read_not_remove(2) & 0x1f;
600                         active_cmd = cmd_buffer->read_not_remove(0);
601                 }
602                 break;
603         case 0x1a:
604                 if(cmd_buffer->count() == 1) {
605                         read_x = cursor_x;
606                         read_y = cursor_y;
607                         active_cmd = cmd_buffer->read_not_remove(0);
608                 }
609                 break;
610         case 0x1b:
611                 if(cmd_buffer->count() == 5) {
612                         scroll_x0 = cmd_buffer->read_not_remove(1) & 0x7f;
613                         scroll_y0 = cmd_buffer->read_not_remove(2) & 0x1f;
614                         scroll_x1 = cmd_buffer->read_not_remove(3) & 0x7f;
615                         scroll_y1 = cmd_buffer->read_not_remove(4) & 0x1f;
616                         active_cmd = cmd_buffer->read_not_remove(0);
617                 }
618                 break;
619         case 0x1c:
620                 if(cmd_buffer->count() == 5) {
621                         int x = cmd_buffer->read_not_remove(1) & 0x7f;
622                         int y = cmd_buffer->read_not_remove(2) & 0x1f;
623                         cvram[y % 25][x % 80].code = cmd_buffer->read_not_remove(3);
624                         cvram[y % 25][x % 80].attr = cmd_buffer->read_not_remove(4);
625                         active_cmd = cmd_buffer->read_not_remove(0);
626                 }
627                 break;
628         case 0x1d:
629                 if(cmd_buffer->count() == 7) {
630                         int x0 = cmd_buffer->read_not_remove(1) & 0x7f;
631                         int y0 = cmd_buffer->read_not_remove(2) & 0x1f;
632                         int x1 = cmd_buffer->read_not_remove(3) & 0x7f;
633                         int y1 = cmd_buffer->read_not_remove(4) & 0x1f;
634                         for(int y = y0; y <= y1 && y <= 24; y++) {
635                                 for(int x = x0; x <= x1 && x <= 79; x++) {
636                                         cvram[y % 25][x % 80].code = cmd_buffer->read_not_remove(5);
637                                         cvram[y % 25][x % 80].attr = cmd_buffer->read_not_remove(6);
638                                 }
639                         }
640                         cursor_x = cursor_y = 0;
641                         write_cr = false;
642                         active_cmd = cmd_buffer->read_not_remove(0);
643                 }
644                 break;
645         case 0x1e:
646                 if(cmd_buffer->count() == 3) {
647                         int x = cmd_buffer->read_not_remove(1) & 0x7f;
648                         int y = cmd_buffer->read_not_remove(2) & 0x1f;
649                         report  = cvram[y % 25][x % 80].code << 0;
650                         report |= cvram[y % 25][x % 80].attr << 8;
651                         active_cmd = cmd_buffer->read_not_remove(0);
652                 }
653                 break;
654         case 0x1f:
655                 if(cmd_buffer->count() == 4) {
656                         mode1 = cmd_buffer->read_not_remove(1);
657                         mode2 = cmd_buffer->read_not_remove(2);
658                         mode3 = cmd_buffer->read_not_remove(3);
659                         active_cmd = cmd_buffer->read_not_remove(0);
660                 }
661                 break;
662         // GRP
663         case 0x06: // F
664                 if(cmd_buffer->count() == 1) {
665 //                      for(int y = 0; y < 25; y++) {
666 //                              for(int x = 0; x < 80; x++) {
667 //                                      cvram[y][x].code = 0x20;
668 //                                      cvram[y][x].attr = 0x0e;
669 //                              }
670 //                      }
671                         memset(gvram, 0, sizeof(gvram));
672                         active_cmd = cmd_buffer->read_not_remove(0);
673                 }
674                 break;
675         case 0x07: // N
676                 if(cmd_buffer->count() == 1) {
677                         erase = true;
678                         active_cmd = cmd_buffer->read_not_remove(0);
679                 }
680                 break;
681         case 0x08: // O
682                 if(cmd_buffer->count() == 1) {
683                         erase = false;
684                         active_cmd = cmd_buffer->read_not_remove(0);
685                 }
686                 break;
687         case 0x11: // z
688                 if(cmd_buffer->count() == 1) {
689                         active_cmd = cmd_buffer->read_not_remove(0);
690                 }
691                 break;
692         case 0x50: // ???
693                 if(cmd_buffer->count() == 2) {
694                         back_color = cmd_buffer->read_not_remove(1) & 7;
695                         active_cmd = cmd_buffer->read_not_remove(0);
696                 }
697                 break;
698         case 0x51: // $14
699                 if(cmd_buffer->count() > 2 && cmd_buffer->read_not_remove(cmd_buffer->count() - 1) == 0) {
700                         int pow = (cmd_buffer->read_not_remove(1) >> 0) & 0x0f;
701                         int rot = (cmd_buffer->read_not_remove(1) >> 4) & 0x03;
702                         
703 //                      int x0, y0;
704 //                      transform_to_vram(point_x, point_y, &x0, &y0);
705 //                      draw_solid_pixel(x0, y0);
706                         for(int i = 2; i < cmd_buffer->count() - 1; i++) {
707                                 draw_char(point_x, point_y, pow, rot, cmd_buffer->read_not_remove(i));
708                                 switch(rot) {
709                                 case 0: point_x += 6 * pow; break;
710                                 case 1: point_y += 6 * pow; break;
711                                 case 2: point_x -= 6 * pow; break;
712                                 case 3: point_y -= 6 * pow; break;
713                                 }
714                         }
715 //                      transform_to_vram(point_x, point_y, &x0, &y0);
716 //                      draw_solid_pixel(x0, y0);
717                         active_cmd = cmd_buffer->read_not_remove(0);
718                 }
719                 break;
720         case 0x53: // M
721                 if(cmd_buffer->count() == 5) {
722                         point_x = get_word(1, cmd_buffer->read_not_remove(1), cmd_buffer->read_not_remove(2));
723                         point_y = get_word(1, cmd_buffer->read_not_remove(3), cmd_buffer->read_not_remove(4));
724                         active_cmd = cmd_buffer->read_not_remove(0);
725                 }
726                 break;
727         case 0x54: // D
728                 if(cmd_buffer->count() == 5) {
729                         int dest_x = get_word(1, cmd_buffer->read_not_remove(1), cmd_buffer->read_not_remove(2));
730                         int dest_y = get_word(1, cmd_buffer->read_not_remove(3), cmd_buffer->read_not_remove(4));
731                         int x0, y0, x1, y1;
732                         transform_to_vram(point_x, point_y, &x0, &y0);
733                         transform_to_vram(dest_x,  dest_y,  &x1, &y1);
734                         draw_texture_line(x0, y0, x1, y1);
735                         point_x = dest_x;
736                         point_y = dest_y;
737                         active_cmd = cmd_buffer->read_not_remove(0);
738                 }
739                 break;
740         case 0x55: // P
741                 if(cmd_buffer->count() == 5) {
742                         point_x = get_word(1, cmd_buffer->read_not_remove(1), cmd_buffer->read_not_remove(2));
743                         point_y = get_word(1, cmd_buffer->read_not_remove(3), cmd_buffer->read_not_remove(4));
744                         int x0, y0;
745                         transform_to_vram(point_x, point_y, &x0, &y0);
746                         draw_solid_pixel(x0, y0);
747                         active_cmd = cmd_buffer->read_not_remove(0);
748                 }
749                 break;
750         case 0x56: // T
751                 if(cmd_buffer->count() == 2) {
752                         texture = cmd_buffer->read_not_remove(1) & 7;
753                         texture_index = 0;
754                         active_cmd = cmd_buffer->read_not_remove(0);
755                 }
756                 break;
757         case 0x59: // p
758                 if(cmd_buffer->count() >= 2) {
759                         int num = cmd_buffer->read_not_remove(1);
760                         if(cmd_buffer->count() == 2 + 4 * num) {
761                                 bool fill = ((cmd_buffer->read_not_remove(2) & 0x80) != 0);
762                                 bool line = ((cmd_buffer->read_not_remove(2) & 0x80) == 0) || ((pattern & 0x80) != 0);
763                                 int x[256], y[256];
764                                 
765                                 for(int i = 0; i < num; i++) {
766                                         x[i] = get_word(1, cmd_buffer->read_not_remove(4 * i + 2), cmd_buffer->read_not_remove(4 * i + 3));
767                                         y[i] = get_word(1, cmd_buffer->read_not_remove(4 * i + 4), cmd_buffer->read_not_remove(4 * i + 5));
768                                 }
769                                 if(num == 0) {
770                                         // do nothing
771                                 } else if(num == 1) {
772                                         int x0, y0;
773                                         transform_to_vram(x[0], y[0], &x0, &y0);
774                                         draw_solid_pixel(x0, y0);
775                                 } else if(num == 2) {
776                                         int x0, y0, x1, y1;
777                                         transform_to_vram(x[0], y[0], &x0, &y0);
778                                         transform_to_vram(x[1], y[1], &x1, &y1);
779                                         draw_texture_line(x0, y0, x1, y1);
780                                 } else {
781                                         if(fill) {
782                                                 int xmin = x[0], ymin = y[0];
783                                                 int xmax = x[0], ymax = y[0];
784                                                 for(int i = 1; i < num; i++) {
785                                                         xmin = min(xmin, x[i]);
786                                                         xmax = max(xmax, x[i]);
787                                                         ymin = min(ymin, y[i]);
788                                                         ymax = max(ymax, y[i]);
789                                                 }
790                                                 int pow = (expand >= 1.0) ? (int)expand * POW : POW;
791                                                 for(int yy = ymin * pow; yy <= ymax * pow; yy++) {
792                                                         double dy = (double)yy / (double)pow;
793                                                         for(int xx = xmin * pow; xx <= xmax * pow; xx++) {
794                                                                 double dx = (double)xx / (double)pow;
795                                                                 // http://home.a00.itscom.net/hatada/c01/algorithm/polygon01.html
796                                                                 bool inside = false;
797                                                                 double old_x = (double)x[num - 1], old_y = (double)y[num - 1];
798                                                                 for(int i = 0; i < num; i++) {
799                                                                         double new_x = (double)x[i], new_y = (double)y[i];
800                                                                         double p1_x = (new_x > old_x) ? old_x : new_x;
801                                                                         double p1_y = (new_x > old_x) ? old_y : new_y;
802                                                                         double p2_x = (new_x > old_x) ? new_x : old_x;
803                                                                         double p2_y = (new_x > old_x) ? new_y : old_y;
804                                                                         if((p1_x < dx) == (dx <= p2_x) && (dy - p1_y) * (p2_x - p1_x) < (p2_y - p1_y) * (dx - p1_x)) {
805                                                                                 inside = !inside;
806                                                                         }
807                                                                         old_x = new_x;
808                                                                         old_y = new_y;
809                                                                 }
810                                                                 if(inside) {
811                                                                         int x0, y0;
812                                                                         transform_to_vram(dx, dy, &x0, &y0);
813                                                                         draw_pattern_pixel(x0, y0);
814                                                                 }
815                                                         }
816                                                 }
817                                         }
818                                         if(line) {
819                                                 int xs, ys;
820                                                 transform_to_vram(x[0], y[0], &xs, &ys);
821                                                 int x0 = xs, y0 = ys, x1, y1;
822                                                 for(int i = 0; i < num; i++) {
823                                                         if(i == num - 1) {
824                                                                 x1 = xs;
825                                                                 y1 = ys;
826                                                         } else {
827                                                                 transform_to_vram(x[i + 1], y[i + 1], &x1, &y1);
828                                                         }
829                                                         if(x0 != x1 || y0 != y1) {
830                                                                 if(fill) {
831                                                                         draw_solid_cont_line(x0, y0, x1, y1);
832                                                                 } else {
833                                                                         draw_texture_cont_line(x0, y0, x1, y1);
834                                                                 }
835                                                                 x0 = x1;
836                                                                 y0 = y1;
837                                                         }
838                                                 }
839                                         }
840                                 }
841                                 active_cmd = cmd_buffer->read_not_remove(0);
842                         }
843                 }
844                 break;
845         case 0x5a: // R
846                 if(cmd_buffer->count() == 9) {
847                         bool fill = ((cmd_buffer->read_not_remove(1) & 0x80) != 0);
848                         bool line = ((cmd_buffer->read_not_remove(1) & 0x80) == 0) || ((pattern & 0x80) != 0);
849                         int ax = get_word(1, cmd_buffer->read_not_remove(1), cmd_buffer->read_not_remove(2));
850                         int ay = get_word(1, cmd_buffer->read_not_remove(3), cmd_buffer->read_not_remove(4));
851                         int bx = get_word(1, cmd_buffer->read_not_remove(5), cmd_buffer->read_not_remove(6));
852                         int by = get_word(1, cmd_buffer->read_not_remove(7), cmd_buffer->read_not_remove(8));
853                         
854                         if(ax > bx) {
855                                 int tx = ax;
856                                 ax = bx;
857                                 bx = tx;
858                         }
859                         if(ay > by) {
860                                 int ty = ay;
861                                 ay = by;
862                                 by = ty;
863                         }
864                         if(fill) {
865                                 int pow = (expand >= 1.0) ? (int)expand * POW : POW;
866                                 for(int yy = ay * pow; yy <= by * pow; yy++) {
867                                         double dy = (double)yy / (double)pow;
868                                         for(int xx = ax * pow; xx <= bx * pow; xx++) {
869                                                 double dx = (double)xx / (double)pow;
870                                                 int x0, y0;
871                                                 transform_to_vram(dx, dy, &x0, &y0);
872                                                 draw_pattern_pixel(x0, y0);
873                                         }
874                                 }
875                         }
876                         if(line) {
877                                 int x0, y0, x1, y1, x2, y2, x3, y3;
878                                 transform_to_vram(ax, ay, &x0, &y0);
879                                 transform_to_vram(bx, ay, &x1, &y1);
880                                 transform_to_vram(bx, by, &x2, &y2);
881                                 transform_to_vram(ax, by, &x3, &y3);
882                                 if(fill) {
883                                         draw_solid_cont_line(x0, y0, x1, y1);
884                                         draw_solid_cont_line(x1, y1, x2, y2);
885                                         draw_solid_cont_line(x2, y2, x3, y3);
886                                         draw_solid_cont_line(x3, y3, x0, y0);
887                                 } else {
888                                         draw_texture_cont_line(x0, y0, x1, y1);
889                                         draw_texture_cont_line(x1, y1, x2, y2);
890                                         draw_texture_cont_line(x2, y2, x3, y3);
891                                         draw_texture_cont_line(x3, y3, x0, y0);
892                                 }
893                         }
894                         active_cmd = cmd_buffer->read_not_remove(0);
895                 }
896                 break;
897         case 0x5d: // G
898                 if(cmd_buffer->count() == 11) {
899                         int x  = get_word(1, cmd_buffer->read_not_remove(1), cmd_buffer->read_not_remove(2));
900                         int y  = get_word(1, cmd_buffer->read_not_remove(3), cmd_buffer->read_not_remove(4));
901                         int nx = get_word(1, cmd_buffer->read_not_remove(5), cmd_buffer->read_not_remove(6));
902                         int dx = cmd_buffer->read_not_remove(7);
903                         int ny = get_word(1, cmd_buffer->read_not_remove(8), cmd_buffer->read_not_remove(9));
904                         int dy = cmd_buffer->read_not_remove(10);
905                         
906                         for(int yy = 0; yy < ny; yy++) {
907                                 for(int xx = 0; xx < nx; xx++) {
908                                         int x0, y0;
909                                         transform_to_vram((double)(x + dx * xx), (double)(y + dy * yy), &x0, &y0);
910                                         draw_solid_pixel(x0, y0);
911                                 }
912                         }
913                         active_cmd = cmd_buffer->read_not_remove(0);
914                 }
915                 break;
916         case 0x5e: // S
917                 if(cmd_buffer->count() == 2) {
918                         pattern = cmd_buffer->read_not_remove(1);
919                         active_cmd = cmd_buffer->read_not_remove(0);
920                 }
921                 break;
922         case 0x5f: // L
923                 if(cmd_buffer->count() == 2) {
924                         fore_color = cmd_buffer->read_not_remove(1) & 7;
925                         active_cmd = cmd_buffer->read_not_remove(0);
926                 }
927                 break;
928         case 0x60: // m
929                 if(cmd_buffer->count() == 9) {
930                         for(int i = 0; i < 8; i++) {
931                                 int c = 255 - cmd_buffer->read_not_remove(i + 1);
932                                 int b = (((c >> 0) & 7) * 255) / 7;
933                                 int r = (((c >> 3) & 7) * 255) / 7;
934                                 int g = (((c >> 6) & 3) * 255) / 3;
935                                 palette_graph[i] = RGB_COLOR(r, g, b);
936                         }
937                         active_cmd = cmd_buffer->read_not_remove(0);
938                 }
939                 break;
940         case 0x61: // a
941                 if(cmd_buffer->count() == 11) {
942                         int cx = get_word(1, cmd_buffer->read_not_remove(1), cmd_buffer->read_not_remove(2));
943                         int cy = get_word(1, cmd_buffer->read_not_remove(3), cmd_buffer->read_not_remove(4));
944                         int r  = get_word(1, cmd_buffer->read_not_remove(5), cmd_buffer->read_not_remove(6));
945                         int t0 = get_word(0, cmd_buffer->read_not_remove(7), cmd_buffer->read_not_remove(8));
946                         int t1 = get_word(0, cmd_buffer->read_not_remove(9), cmd_buffer->read_not_remove(10));
947                         
948                         while(t0 < 0) {
949                                 t0 += 36000;
950                                 t1 += 36000;
951                         }
952                         while(t0 > t1) {
953                                 t1 += 36000;
954                         }
955                         while((t1 - t0) > 36000) {
956                                 t1 -= 36000;
957                         }
958                         int xs, ys, xe, ye;
959                         double rad;
960                         rad = 2.0 * M_PI * (double)t0 / 36000.0;
961                         transform_to_vram((double)cx + (double)r * cos(rad), (double)cy + (double)r * sin(rad), &xs, &ys);
962                         rad = 2.0 * M_PI * (double)t1 / 36000.0;
963                         transform_to_vram((double)cx + (double)r * cos(rad), (double)cy + (double)r * sin(rad), &xe, &ye);
964                         int x0 = xs, y0 = ys, x1, y1;
965                         for(; t0 < t1; t0 += 100) {
966                                 double rad = 2.0 * M_PI * (double)t0 / 36000.0;
967                                 transform_to_vram((double)cx + (double)r * cos(rad), (double)cy + (double)r * sin(rad), &x1, &y1);
968                                 if(x0 != x1 || y0 != y1) {
969                                         draw_texture_cont_line(x0, y0, x1, y1);
970                                         x0 = x1;
971                                         y0 = y1;
972                                 }
973                         }
974                         if(x0 != xe || y0 != ye) {
975                                 draw_texture_line(x0, y0, xe, ye);
976                         }
977                         active_cmd = cmd_buffer->read_not_remove(0);
978                 }
979                 break;
980         case 0x62: // f
981                 if(cmd_buffer->count() == 11) {
982                         bool fill = ((cmd_buffer->read_not_remove(5) & 0x80) != 0);
983                         bool line = ((cmd_buffer->read_not_remove(5) & 0x80) == 0) || ((pattern & 0x80) != 0);
984                         int cx = get_word(1, cmd_buffer->read_not_remove(1), cmd_buffer->read_not_remove(2));
985                         int cy = get_word(1, cmd_buffer->read_not_remove(3), cmd_buffer->read_not_remove(4));
986                         int r  = get_word(1, cmd_buffer->read_not_remove(5), cmd_buffer->read_not_remove(6));
987                         int t0 = get_word(0, cmd_buffer->read_not_remove(7), cmd_buffer->read_not_remove(8));
988                         int t1 = get_word(0, cmd_buffer->read_not_remove(9), cmd_buffer->read_not_remove(10));
989                         
990                         while(t0 < 0) {
991                                 t0 += 36000;
992                                 t1 += 36000;
993                         }
994                         while(t0 > t1) {
995                                 t1 += 36000;
996                         }
997                         while((t1 - t0) > 36000) {
998                                 t1 -= 36000;
999                         }
1000                         int xc, yc, xs, ys, xe, ye;
1001                         transform_to_vram((double)cx, (double)cy, &xc, &yc);
1002                         double rad;
1003                         rad = 2.0 * M_PI * (double)t0 / 36000.0;
1004                         transform_to_vram((double)cx + (double)r * cos(rad), (double)cy + (double)r * sin(rad), &xs, &ys);
1005                         rad = 2.0 * M_PI * (double)t1 / 36000.0;
1006                         transform_to_vram((double)cx + (double)r * cos(rad), (double)cy + (double)r * sin(rad), &xe, &ye);
1007                         
1008                         if(fill) {
1009                                 int pow = (expand >= 1.0) ? (int)expand * POW : POW;
1010                                 double dr2 = (double)r * (double)r;
1011                                 for(int yy = -abs(r) * pow; yy <= abs(r) * pow; yy++) {
1012                                         double dy = (double)yy / (double)pow;
1013                                         double dy2 = dy * dy;
1014                                         for(int xx = -abs(r) * pow; xx <= abs(r) * pow; xx++) {
1015                                                 double dx = (double)xx / (double)pow;
1016                                                 double dx2 = dx * dx;
1017                                                 if(dx2 + dy2 <= dr2) {
1018                                                         double deg = atan2(dy, dx) * 180.0 / M_PI * 100.0;
1019                                                         while(deg < t0) {
1020                                                                 deg += 36000.0;
1021                                                         }
1022                                                         if(/*deg >= t0 && */deg <= t1) {
1023                                                                 int x0, y0;
1024                                                                 transform_to_vram((double)cx + dx, (double)cy + dy, &x0, &y0);
1025                                                                 draw_pattern_pixel(x0, y0);
1026                                                         }
1027                                                 }
1028                                         }
1029                                 }
1030                         }
1031                         if(line) {
1032                                 if(fill) {
1033                                         draw_solid_cont_line(xc, yc, xs, ys);
1034                                 } else {
1035                                         draw_texture_cont_line(xc, yc, xs, ys);
1036                                 }
1037                                 int x0 = xs, y0 = ys, x1, y1;
1038                                 for(; t0 < t1; t0 += 100) {
1039                                         double rad = 2.0 * M_PI * (double)t0 / 36000.0;
1040                                         transform_to_vram((double)cx + (double)r * cos(rad), (double)cy + (double)r * sin(rad), &x1, &y1);
1041                                         if(x0 != x1 || y0 != y1) {
1042                                                 if(fill) {
1043                                                         draw_solid_cont_line(x0, y0, x1, y1);
1044                                                 } else {
1045                                                         draw_texture_cont_line(x0, y0, x1, y1);
1046                                                 }
1047                                                 x0 = x1;
1048                                                 y0 = y1;
1049                                         }
1050                                 }
1051                                 if(x0 != xe || y0 != ye) {
1052                                         if(fill) {
1053                                                 draw_solid_cont_line(x0, y0, xe, ye);
1054                                         } else {
1055                                                 draw_texture_cont_line(x0, y0, xe, ye);
1056                                         }
1057                                 }
1058                                 if(fill) {
1059                                         draw_solid_cont_line(xe, ye, xc, yc);
1060                                 } else {
1061                                         draw_texture_cont_line(xe, ye, xc, yc);
1062                                 }
1063                         }
1064                         active_cmd = cmd_buffer->read_not_remove(0);
1065                 }
1066                 break;
1067         case 0x64: // n
1068                 if(cmd_buffer->count() == 2) {
1069                         if(cmd_buffer->read_not_remove(1) & 1) {
1070                                 expand = 1.0;
1071                         }
1072                         if(cmd_buffer->read_not_remove(1) & 2) {
1073                                 rotate = 0;
1074                         }
1075                         if(cmd_buffer->read_not_remove(1) & 4) {
1076                                 translate_x = translate_y = 0;
1077                         }
1078                         active_cmd = cmd_buffer->read_not_remove(0);
1079                 }
1080                 break;
1081         case 0x65: // c
1082                 if(cmd_buffer->count() == 7) {
1083                         bool fill = ((cmd_buffer->read_not_remove(5) & 0x80) != 0);
1084                         bool line = ((cmd_buffer->read_not_remove(5) & 0x80) == 0) || ((pattern & 0x80) != 0);
1085                         int cx = get_word(1, cmd_buffer->read_not_remove(1), cmd_buffer->read_not_remove(2));
1086                         int cy = get_word(1, cmd_buffer->read_not_remove(3), cmd_buffer->read_not_remove(4));
1087                         int r  = get_word(1, cmd_buffer->read_not_remove(5), cmd_buffer->read_not_remove(6));
1088                         
1089                         if(fill) {
1090                                 int pow = (expand >= 1.0) ? (int)expand * POW : POW;
1091                                 double dr2 = (double)r * (double)r;
1092                                 for(int yy = -abs(r) * pow; yy <= abs(r) * pow; yy++) {
1093                                         double dy = (double)yy / (double)pow;
1094                                         double dy2 = dy * dy;
1095                                         for(int xx = -abs(r) * pow; xx <= abs(r) * pow; xx++) {
1096                                                 double dx = (double)xx / (double)pow;
1097                                                 double dx2 = dx * dx;
1098                                                 if(dx2 + dy2 <= dr2) {
1099                                                         int x0, y0;
1100                                                         transform_to_vram((double)cx + dx, (double)cy + dy, &x0, &y0);
1101                                                         draw_pattern_pixel(x0, y0);
1102                                                 }
1103                                         }
1104                                 }
1105                         }
1106                         if(line) {
1107                                 int xs, ys;
1108                                 transform_to_vram((double)(cx + r), (double)cy, &xs, &ys);
1109                                 int x0 = xs, y0 = ys, x1, y1;
1110                                 for(int i = 1; i <= 360; i++) {
1111                                         if(i == 360) {
1112                                                 x1 = xs;
1113                                                 y1 = ys;
1114                                         } else {
1115                                                 double rad = 2.0 * M_PI * (double)i / 360.0;
1116                                                 transform_to_vram((double)cx + (double)r * cos(rad), (double)cy + (double)r * sin(rad), &x1, &y1);
1117                                         }
1118                                         if(x0 != x1 || y0 != y1) {
1119                                                 if(fill) {
1120                                                         draw_solid_cont_line(x0, y0, x1, y1);
1121                                                 } else {
1122                                                         draw_texture_cont_line(x0, y0, x1, y1);
1123                                                 }
1124                                                 x0 = x1;
1125                                                 y0 = y1;
1126                                         }
1127                                 }
1128                         }
1129                         active_cmd = cmd_buffer->read_not_remove(0);
1130                 }
1131                 break;
1132         case 0x66: // e
1133                 if(cmd_buffer->count() == 9) {
1134                         bool fill = ((cmd_buffer->read_not_remove(5) & 0x80) != 0);
1135                         bool line = ((cmd_buffer->read_not_remove(5) & 0x80) == 0) || ((pattern & 0x80) != 0);
1136                         int cx = get_word(1, cmd_buffer->read_not_remove(1), cmd_buffer->read_not_remove(2));
1137                         int cy = get_word(1, cmd_buffer->read_not_remove(3), cmd_buffer->read_not_remove(4));
1138                         int a  = get_word(1, cmd_buffer->read_not_remove(5), cmd_buffer->read_not_remove(6));
1139                         int b  = get_word(1, cmd_buffer->read_not_remove(7), cmd_buffer->read_not_remove(8));
1140                         
1141                         if(fill) {
1142                                 int pow = (expand >= 1.0) ? (int)expand * POW : POW;
1143                                 double da2 = (double)a * (double)a, db2 = (double)b * (double)b;
1144                                 double da2b2 = da2 * db2;
1145                                 for(int yy = -abs(b) * pow; yy <= abs(b) * pow; yy++) {
1146                                         double dy = (double)yy / (double)pow;
1147                                         double dy2 = dy * dy;
1148                                         for(int xx = -abs(a) * pow; xx <= abs(a) * pow; xx++) {
1149                                                 double dx = (double)xx / (double)pow;
1150                                                 double dx2 = dx * dx;
1151                                                 if(db2 * dx2 + da2 * dy2 <= da2b2) {
1152                                                         int x0, y0;
1153                                                         transform_to_vram((double)cx + dx, (double)cy + dy, &x0, &y0);
1154                                                         draw_pattern_pixel(x0, y0);
1155                                                 }
1156                                         }
1157                                 }
1158                         }
1159                         if(line) {
1160                                 int xs, ys;
1161                                 transform_to_vram((double)(cx + a), (double)cy, &xs, &ys);
1162                                 int x0 = xs, y0 = ys, x1, y1;
1163                                 for(int i = 1; i <= 360; i++) {
1164                                         if(i == 360) {
1165                                                 x1 = xs;
1166                                                 y1 = ys;
1167                                         } else {
1168                                                 double rad = 2.0 * M_PI * (double)i / 360.0;
1169                                                 transform_to_vram((double)cx + (double)a * cos(rad), (double)cy + (double)b * sin(rad), &x1, &y1);
1170                                         }
1171                                         if(x0 != x1 || y0 != y1) {
1172                                                 if(fill) {
1173                                                         draw_solid_cont_line(x0, y0, x1, y1);
1174                                                 } else {
1175                                                         draw_texture_cont_line(x0, y0, x1, y1);
1176                                                 }
1177                                                 x0 = x1;
1178                                                 y0 = y1;
1179                                         }
1180                                 }
1181                         }
1182                         active_cmd = cmd_buffer->read_not_remove(0);
1183                 }
1184                 break;
1185         case 0x68: // C
1186                 if(cmd_buffer->count() == 3) {
1187                         int num = cmd_buffer->read_not_remove(1) & 7;
1188                         int c = 255 - cmd_buffer->read_not_remove(2);
1189                         int b = (((c >> 0) & 7) * 255) / 7;
1190                         int r = (((c >> 3) & 7) * 255) / 7;
1191                         int g = (((c >> 6) & 3) * 255) / 3;
1192                         palette_graph[num] = RGB_COLOR(r, g, b);
1193                         active_cmd = cmd_buffer->read_not_remove(0);
1194                 }
1195                 break;
1196         case 0x70: // w
1197                 if(cmd_buffer->count() == 9) {
1198                         window_x0 = get_word(1, cmd_buffer->read_not_remove(1), cmd_buffer->read_not_remove(2));
1199                         window_y0 = get_word(1, cmd_buffer->read_not_remove(3), cmd_buffer->read_not_remove(4));
1200                         window_x1 = get_word(1, cmd_buffer->read_not_remove(5), cmd_buffer->read_not_remove(6));
1201                         window_y1 = get_word(1, cmd_buffer->read_not_remove(7), cmd_buffer->read_not_remove(8));
1202                         active_cmd = cmd_buffer->read_not_remove(0);
1203                 }
1204                 break;
1205         case 0x71: // v
1206                 if(cmd_buffer->count() == 9) {
1207                         view_x0 = get_word(1, cmd_buffer->read_not_remove(1), cmd_buffer->read_not_remove(2));
1208                         view_y0 = get_word(1, cmd_buffer->read_not_remove(3), cmd_buffer->read_not_remove(4));
1209                         view_x1 = get_word(1, cmd_buffer->read_not_remove(5), cmd_buffer->read_not_remove(6));
1210                         view_y1 = get_word(1, cmd_buffer->read_not_remove(7), cmd_buffer->read_not_remove(8));
1211                         active_cmd = cmd_buffer->read_not_remove(0);
1212                 }
1213                 break;
1214         case 0x72: // s
1215                 if(cmd_buffer->count() == 2) {
1216                         expand *= (double)cmd_buffer->read_not_remove(1) / 16.0;
1217                         active_cmd = cmd_buffer->read_not_remove(0);
1218                 }
1219                 break;
1220         case 0x74: // t
1221                 if(cmd_buffer->count() == 5) {
1222                         translate_x = get_word(1, cmd_buffer->read_not_remove(1), cmd_buffer->read_not_remove(2));
1223                         translate_y = get_word(1, cmd_buffer->read_not_remove(3), cmd_buffer->read_not_remove(4));
1224                         active_cmd = cmd_buffer->read_not_remove(0);
1225                 }
1226                 break;
1227         case 0x75: // r
1228                 if(cmd_buffer->count() == 4) {
1229                         rotate += get_word(1, cmd_buffer->read_not_remove(2), cmd_buffer->read_not_remove(3));
1230                         while(rotate < 0) {
1231                                 rotate += 36000;
1232                         }
1233                         rotate %= 36000;
1234                         active_cmd = cmd_buffer->read_not_remove(0);
1235                 }
1236                 break;
1237         case 0x7f: // I
1238                 if(cmd_buffer->count() == 2) {
1239                         window_x0 = view_x0 = -256;
1240                         window_y0 = view_y0 = -192;
1241                         window_x1 = view_x1 =  255;
1242                         window_y1 = view_y1 =  191;
1243                         expand = 1.0;
1244                         rotate = 0;
1245                         translate_x = translate_y = 0;
1246                         point_x = point_y = 0;
1247                         fore_color = 7;
1248                         back_color = 0;
1249                         erase = false;
1250                         texture = texture_index = 0;
1251                         pattern = 0;
1252                         active_cmd = cmd_buffer->read_not_remove(0);
1253                 }
1254                 break;
1255         default:
1256                 emu->force_out_debug_log(_T("Unknown GPP: %02X\n\n"), cmd_buffer->read_not_remove(0));
1257                 cmd_buffer->clear();
1258                 break;
1259         }
1260 }
1261
1262 void DISPLAY::put_code(uint8_t data)
1263 {
1264         switch(data) {
1265         case 0x00:
1266                 break;
1267         case 0x08: // BS
1268         case 0x1d:
1269                 if(--cursor_x < scroll_x0) {
1270                         if(--cursor_y < scroll_y0) {
1271                                 cursor_x = scroll_x0;
1272                                 cursor_y = scroll_y0;
1273                         } else {
1274                                 cursor_x = scroll_x1;
1275                         }
1276                 }
1277                 break;
1278         case 0x0a: // LF
1279                 if(++cursor_y > scroll_y1) {
1280                         cursor_y = scroll_y1;
1281                         scroll();
1282                 }
1283                 break;
1284         case 0x0d: // CR
1285                 cvram[cursor_y % 25][cursor_x % 80].code = data;
1286                 cvram[cursor_y % 25][cursor_x % 80].attr = mode1;
1287                 cursor_x = scroll_x0;
1288                 write_cr = true;
1289                 break;
1290         case 0x10: // FS
1291         case 0x1c: // FS
1292                 if(++cursor_x > scroll_x1) {
1293                         if(++cursor_y > scroll_y1) {
1294                                 cursor_y = scroll_y1;
1295                                 scroll();
1296                         }
1297                         cursor_x = scroll_x0;
1298                 }
1299                 break;
1300         case 0x1e: // UP
1301                 if(--cursor_y < scroll_y0) {
1302                         cursor_y = scroll_y0;
1303                 }
1304                 break;
1305         case 0x1f: // DOWN
1306                 if(++cursor_y > scroll_y1) {
1307                         cursor_y = scroll_y1;
1308                 }
1309                 break;
1310         default:
1311                 cvram[cursor_y % 25][cursor_x % 80].code = data;
1312                 cvram[cursor_y % 25][cursor_x % 80].attr = mode1;
1313                 if(++cursor_x > scroll_x1) {
1314                         if(++cursor_y > scroll_y1) {
1315                                 cursor_y = scroll_y1;
1316                                 scroll();
1317                         }
1318                         cursor_x = scroll_x0;
1319                 }
1320                 break;
1321         }
1322 }
1323
1324 uint8_t DISPLAY::get_code()
1325 {
1326         uint8_t data = 0x0d;
1327         
1328         if(write_cr) {
1329                 if((data = cvram[read_y % 25][read_x % 80].code) != 0x0d) {
1330                         if(++read_x > scroll_x1) {
1331                                 if(++read_y > scroll_y1) {
1332                                         write_cr = false; // ???
1333                                 }
1334                                 read_x = scroll_x0;
1335                         }
1336                 } else {
1337                         write_cr = false;
1338                 }
1339         }
1340         return data;
1341 }
1342
1343 void DISPLAY::scroll()
1344 {
1345         for(int y = scroll_y0; y <= scroll_y1 - 1; y++) {
1346                 for(int x = scroll_x0; x <= scroll_x1; x++) {
1347                         cvram[y % 25][x % 80].code = cvram[(y + 1) % 25][x % 80].code;
1348                         cvram[y % 25][x % 80].attr = cvram[(y + 1) % 25][x % 80].attr;
1349                 }
1350         }
1351         for(int x = scroll_x0; x <= scroll_x1; x++) {
1352                 cvram[scroll_y1 % 25][x % 80].code = 0x20;
1353                 cvram[scroll_y1 % 25][x % 80].attr = mode1;
1354         }
1355 }
1356
1357 void DISPLAY::transform(double world_x, double world_y, double *x, double *y)
1358 {
1359         double rad = 2.0 * M_PI * (double)rotate / 36000.0;
1360         double tmp_x = world_x * expand;
1361         double tmp_y = world_y * expand;
1362         *x = (double)translate_x + tmp_x * cos(rad) - tmp_y * sin(rad);
1363         *y = (double)translate_y + tmp_x * sin(rad) + tmp_y * cos(rad);
1364 }
1365
1366 void DISPLAY::world_to_view(double world_x, double world_y, double *x, double *y)
1367 {
1368         *x = view_x0 + (double)(view_x1 - view_x0 + 1) * (world_x - (double)window_x0 + 1.0) / (double)(window_x1 - window_x0 + 1);
1369         *y = view_y0 + (double)(view_y1 - view_y0 + 1) * (world_y - (double)window_y0 + 1.0) / (double)(window_y1 - window_y0 + 1);
1370 }
1371
1372 void DISPLAY::view_to_vram(double view_x, double view_y, int *x, int *y)
1373 {
1374         double tmp_x = 320.0 + (view_x * 320.0) / 256.0;
1375         double tmp_y = 239.0 - (view_y * 320.0) / 256.0;
1376         *x = (int)(tmp_x + 0.5 - (tmp_x < 0));
1377         *y = (int)(tmp_y + 0.5 - (tmp_y < 0));
1378 }
1379
1380 void DISPLAY::transform_to_vram(double world_x, double world_y, int *x, int *y)
1381 {
1382         double trans_x, trans_y;
1383         double view_x, view_y;
1384         
1385         transform(world_x, world_y, &trans_x, &trans_y);
1386         world_to_view(trans_x, trans_y, &view_x, &view_y);
1387         view_to_vram(view_x, view_y, x, y);
1388 }
1389
1390 void DISPLAY::draw_solid_pixel(int x, int y)
1391 {
1392         if(x >= 0 && x < 640 && y >= 0 && y < 480) {
1393                 gvram[y][x] = erase ? back_color : fore_color;
1394         }
1395 }
1396
1397 void DISPLAY::draw_texture_pixel(int x, int y)
1398 {
1399         if(texture_index < 0 || texture_index >= texture_table[texture & 7].length) {
1400                 texture_index = 0;
1401         }
1402         if(texture_table[texture & 7].dots[texture_index]) {
1403                 draw_solid_pixel(x, y);
1404         } else {
1405 //              erase = !erase;
1406 //              draw_solid_pixel(x, y);
1407 //              erase = !erase;
1408         }
1409         texture_index++;
1410 }
1411
1412 void DISPLAY::draw_pattern_pixel(int x, int y)
1413 {
1414         if(pattern_table[pattern & 127][y & 15] & (0x8000 >> (x & 15))) {
1415                 draw_solid_pixel(x, y);
1416         } else {
1417 //              erase = !erase;
1418 //              draw_solid_pixel(x, y);
1419 //              erase = !erase;
1420         }
1421 }
1422
1423 void DISPLAY::draw_solid_line(int x0, int y0, int x1, int y1)
1424 {
1425         int _texture = texture;
1426         int _index = texture_index;
1427         
1428         texture = texture_index = 0;
1429         draw_texture_line(x0, y0, x1, y1);
1430         
1431         texture = _texture;
1432         texture_index = _index;
1433 }
1434
1435 void DISPLAY::draw_solid_cont_line(int x0, int y0, int x1, int y1)
1436 {
1437         int _texture = texture;
1438         int _index = texture_index;
1439         
1440         texture = texture_index = 0;
1441         draw_texture_cont_line(x0, y0, x1, y1);
1442         
1443         texture = _texture;
1444         texture_index = _index;
1445 }
1446
1447 void DISPLAY::draw_texture_line(int x0, int y0, int x1, int y1)
1448 {
1449         draw_texture_cont_line(x0, y0, x1, y1);
1450         draw_texture_pixel(x1, y1);
1451 }
1452
1453 void DISPLAY::draw_texture_cont_line(int x0, int y0, int x1, int y1)
1454 {
1455         // do not set the last pixel
1456         int dx = abs(x1 - x0);
1457         int dy = abs(y1 - y0);
1458         int sx = (x0 < x1) ? 1 : -1;
1459         int sy = (y0 < y1) ? 1 : -1;
1460         int e1 = dx - dy;
1461         
1462         while(!(x0 == x1 && y0 == y1)) {
1463                 draw_texture_pixel(x0, y0);
1464                 int e2 = 2 * e1;
1465                 if(e2 > -dy) {
1466                         e1 -= dy;
1467                         x0 += sx;
1468                 }
1469                 if(e2 < dx) {
1470                         e1 += dx;
1471                         y0 += sy;
1472                 }
1473         }
1474 }
1475
1476 void DISPLAY::draw_char(int x, int y, int pow, int rot, int code)
1477 {
1478         // KST32B fcsf1_shp_src/csf12shp.c
1479         static const double vector[4][4] = {
1480                 { 1,  0,  0,  1},
1481                 { 0,  1, -1,  0},
1482                 {-1,  0,  0, -1},
1483                 { 0, -1,  1,  0},
1484         };
1485         int from_x = 0, to_x = 0, from_y = 0;
1486         
1487         for(int i = 0; i < 32; i++) {
1488                 uint8_t data = char_table[code][i];
1489                 int value, draw_x = 0, draw_y = 0;
1490                 
1491                 if(data >= 0x21 && data <= 0x26) {
1492                         from_x = to_x = data - 0x21;
1493                 } else if(data >= 0x28 && data <= 0x3f) {
1494                         from_x = to_x = data - 0x28 + 6;
1495                 } else if(data >= 0x40 && data <= 0x5b) {
1496                         value = data - 0x40;
1497                         draw_x = 1;
1498                 } else if(data >= 0x5e && data <= 0x5f) {
1499                         value = data - 0x5e + 28;
1500                         draw_x = 1;
1501                 } else if(data >= 0x60 && data <= 0x7d) {
1502                         to_x = data - 0x60;
1503                 } else if(data == 0x7e) {
1504                         from_y = 0;
1505                 } else if(data >= 0xa1 && data <= 0xbf) {
1506                         from_y = data - 0xa1 + 1;
1507                 } else if(data >= 0xc0 && data <= 0xdf) {
1508                         value = data - 0xc0;
1509                         draw_y = 1;
1510                 } else {
1511                         break;
1512                 }
1513                 if(draw_x) {
1514                         // (from_x, from_y) - (value, from_y)
1515                         double xs = (double)from_x * 6.0 * (double)pow / 16.0;
1516                         double ys = (double)from_y * 8.0 * (double)pow / 32.0;
1517                         double xe = (double)value  * 6.0 * (double)pow / 16.0;
1518                         double ye = (double)from_y * 8.0 * (double)pow / 32.0;
1519                         int x0, y0, x1, y1;
1520                         transform_to_vram(point_x + xs * vector[rot][0] + ys * vector[rot][2], point_y + xs * vector[rot][1] + ys * vector[rot][3], &x0, &y0);
1521                         transform_to_vram(point_x + xe * vector[rot][0] + ye * vector[rot][2], point_y + xe * vector[rot][1] + ye * vector[rot][3], &x1, &y1);
1522                         draw_solid_line(x0, y0, x1, y1);
1523                         from_x = to_x = value;
1524                 } else if(draw_y) {
1525                         // (from_x, from_y) - (to_x, value)
1526                         double xs = (double)from_x * 6.0 * (double)pow / 16.0;
1527                         double ys = (double)from_y * 8.0 * (double)pow / 32.0;
1528                         double xe = (double)to_x   * 6.0 * (double)pow / 16.0;
1529                         double ye = (double)value  * 8.0 * (double)pow / 32.0;
1530                         int x0, y0, x1, y1;
1531                         transform_to_vram(point_x + xs * vector[rot][0] + ys * vector[rot][2], point_y + xs * vector[rot][1] + ys * vector[rot][3], &x0, &y0);
1532                         transform_to_vram(point_x + xe * vector[rot][0] + ye * vector[rot][2], point_y + xe * vector[rot][1] + ye * vector[rot][3], &x1, &y1);
1533                         draw_solid_line(x0, y0, x1, y1);
1534                         from_x = to_x;
1535                         from_y = value;
1536                 }
1537         }
1538 }
1539
1540 void DISPLAY::draw_screen()
1541 {
1542         // render screen
1543         memset(screen, 0, sizeof(screen));
1544         draw_text();
1545         
1546         // copy to real screen
1547         for(int y = 0; y < 480; y++) {
1548                 scrntype_t* dest = emu->get_screen_buffer(y);
1549                 uint8_t* src_t = screen[y];
1550                 for(int x = 0; x < 640; x++) {
1551                         dest[x] = src_t[x] ? palette_text[src_t[x]] : palette_graph[gvram[y][x]];
1552                 }
1553         }
1554         emu->screen_skip_line(false);
1555 }
1556
1557 void DISPLAY::draw_text()
1558 {
1559         for(int y = 0; y < 25; y++) {
1560                 for(int x = 0; x < 80; x++) {
1561                         uint8_t code = cvram[y][x].code;
1562                         uint8_t fore = (mode3 & 1) ? (cvram[y][x].attr >> 1) & 7 : 7;
1563                         uint8_t back = (mode3 & 1) ? (cvram[y][x].attr >> 5) & 7 : 0;
1564                         
1565                         if(fore == back) {
1566                                 fore = 7 - back;
1567                         }
1568                         for(int l = 0; l < 16; l++) {
1569                                 uint8_t pat = (mode3 & 4) ? 0 : font[((mode3 & 2) ? 0x1000 : 0) + (code << 4) + l];
1570                                 uint8_t* d = &screen[y * 19 + l + 2][x << 3];
1571                                 
1572                                 d[0] = (pat & 0x80) ? fore : back;
1573                                 d[1] = (pat & 0x40) ? fore : back;
1574                                 d[2] = (pat & 0x20) ? fore : back;
1575                                 d[3] = (pat & 0x10) ? fore : back;
1576                                 d[4] = (pat & 0x08) ? fore : back;
1577                                 d[5] = (pat & 0x04) ? fore : back;
1578                                 d[6] = (pat & 0x02) ? fore : back;
1579                                 d[7] = (pat & 0x01) ? fore : back;
1580                         }
1581                         if(x == cursor_x && y == cursor_y && (mode2 & 0x10) && (blink & 0x10)) {
1582                                 if(mode2 & 0x80) {
1583                                         for(int l = 0; l < 16; l++) {
1584                                                 uint8_t* d = &screen[y * 19 + l + 2][x << 3];
1585                                                 for(int c = 0; c < 8; c++) {
1586                                                         d[c] = 7 - d[c];
1587                                                 }
1588                                         }
1589                                 } else {
1590                                         for(int l = 16; l < 18; l++) {
1591                                                 uint8_t* d = &screen[y * 19 + l + 2][x << 3];
1592                                                 memset(d, 7, 8);
1593                                         }
1594                                 }
1595                         }
1596                 }
1597         }
1598 }
1599
1600 #define STATE_VERSION   2
1601
1602 #include "../../statesub.h"
1603
1604 void DISPLAY::decl_state()
1605 {
1606         enter_decl_state(STATE_VERSION);
1607         
1608         DECL_STATE_ENTRY_FIFO(cmd_buffer);
1609         DECL_STATE_ENTRY_INT32(active_cmd);
1610         DECL_STATE_ENTRY_UINT8(dpp_data);
1611         DECL_STATE_ENTRY_UINT8(dpp_ctrl);
1612         DECL_STATE_ENTRY_INT32(scroll_x0);
1613         DECL_STATE_ENTRY_INT32(scroll_y0);
1614         DECL_STATE_ENTRY_INT32(scroll_x1);
1615         DECL_STATE_ENTRY_INT32(scroll_y1);
1616         DECL_STATE_ENTRY_INT32(cursor_x);
1617         DECL_STATE_ENTRY_INT32(cursor_y);
1618         DECL_STATE_ENTRY_INT32(read_x);
1619         DECL_STATE_ENTRY_INT32(read_y);
1620         DECL_STATE_ENTRY_UINT8(mode1);
1621         DECL_STATE_ENTRY_UINT8(mode2);
1622         DECL_STATE_ENTRY_UINT8(mode3);
1623         DECL_STATE_ENTRY_UINT32(report);
1624         DECL_STATE_ENTRY_BOOL(write_cr);
1625         for(int i = 0; i < 25; i++) {
1626                 DECL_STATE_ENTRY_UINT8_STRIDE((cvram[i][0].code), 80, sizeof(cvram[i][0]));
1627                 DECL_STATE_ENTRY_UINT8_STRIDE((cvram[i][0].attr), 80, sizeof(cvram[i][0]));
1628         }                                                                         
1629         DECL_STATE_ENTRY_2D_ARRAY(gvram, 480, 640);
1630         DECL_STATE_ENTRY_INT32(window_x0);
1631         DECL_STATE_ENTRY_INT32(window_y0);
1632         DECL_STATE_ENTRY_INT32(window_x1);
1633         DECL_STATE_ENTRY_INT32(window_y1);
1634         DECL_STATE_ENTRY_INT32(view_x0);
1635         DECL_STATE_ENTRY_INT32(view_y0);
1636         DECL_STATE_ENTRY_INT32(view_x1);
1637         DECL_STATE_ENTRY_INT32(view_y1);
1638         DECL_STATE_ENTRY_DOUBLE(expand);
1639         DECL_STATE_ENTRY_INT32(rotate);
1640         DECL_STATE_ENTRY_INT32(translate_x);
1641         DECL_STATE_ENTRY_INT32(translate_y);
1642         DECL_STATE_ENTRY_INT32(point_x);
1643         DECL_STATE_ENTRY_INT32(point_y);
1644         DECL_STATE_ENTRY_INT32(fore_color);
1645         DECL_STATE_ENTRY_INT32(back_color);
1646         DECL_STATE_ENTRY_BOOL(erase);
1647         DECL_STATE_ENTRY_INT32(texture);
1648         DECL_STATE_ENTRY_INT32(texture_index);
1649         DECL_STATE_ENTRY_INT32(pattern);
1650         DECL_STATE_ENTRY_SCRNTYPE_T_1D_ARRAY(palette_graph, sizeof(palette_graph) / sizeof(scrntype_t));
1651         DECL_STATE_ENTRY_INT32(blink);
1652
1653         leave_decl_state();
1654 }
1655
1656 void DISPLAY::save_state(FILEIO* state_fio)
1657 {
1658         if(state_entry != NULL) {
1659                 state_entry->save_state(state_fio);
1660         }
1661 //      state_fio->FputUint32(STATE_VERSION);
1662 //      state_fio->FputInt32(this_device_id);
1663 //      
1664 //      cmd_buffer->save_state((void *)state_fio);
1665 //      state_fio->FputInt32(active_cmd);
1666 //      state_fio->FputUint8(dpp_data);
1667 //      state_fio->FputUint8(dpp_ctrl);
1668 //      state_fio->FputInt32(scroll_x0);
1669 //      state_fio->FputInt32(scroll_y0);
1670 //      state_fio->FputInt32(scroll_x1);
1671 //      state_fio->FputInt32(scroll_y1);
1672 //      state_fio->FputInt32(cursor_x);
1673 //      state_fio->FputInt32(cursor_y);
1674 //      state_fio->FputInt32(read_x);
1675 //      state_fio->FputInt32(read_y);
1676 //      state_fio->FputUint8(mode1);
1677 //      state_fio->FputUint8(mode2);
1678 //      state_fio->FputUint8(mode3);
1679 //      state_fio->FputUint32(report);
1680 //      state_fio->FputBool(write_cr);
1681 //      state_fio->Fwrite(cvram, sizeof(cvram), 1);
1682 //      state_fio->Fwrite(gvram, sizeof(gvram), 1);
1683 //      state_fio->FputInt32(window_x0);
1684 //      state_fio->FputInt32(window_y0);
1685 //      state_fio->FputInt32(window_x1);
1686 //      state_fio->FputInt32(window_y1);
1687 //      state_fio->FputInt32(view_x0);
1688 //      state_fio->FputInt32(view_y0);
1689 //      state_fio->FputInt32(view_x1);
1690 //      state_fio->FputInt32(view_y1);
1691 //      state_fio->FputDouble(expand);
1692 //      state_fio->FputInt32(rotate);
1693 //      state_fio->FputInt32(translate_x);
1694 //      state_fio->FputInt32(translate_y);
1695 //      state_fio->FputInt32(point_x);
1696 //      state_fio->FputInt32(point_y);
1697 //      state_fio->FputInt32(fore_color);
1698 //      state_fio->FputInt32(back_color);
1699 //      state_fio->FputBool(erase);
1700 //      state_fio->FputInt32(texture);
1701 //      state_fio->FputInt32(texture_index);
1702 //      state_fio->FputInt32(pattern);
1703 //      state_fio->Fwrite(palette_graph, sizeof(palette_graph), 1);
1704 //      state_fio->FputInt32(blink);
1705 }
1706
1707 bool DISPLAY::load_state(FILEIO* state_fio)
1708 {
1709         bool mb = false;
1710         if(state_entry != NULL) {
1711                 mb = state_entry->load_state(state_fio);
1712         }
1713         if(!mb) {
1714                 return false;
1715         }
1716 //      if(state_fio->FgetUint32() != STATE_VERSION) {
1717 //              return false;
1718 //      }
1719 //      if(state_fio->FgetInt32() != this_device_id) {
1720 //              return false;
1721 //      }
1722 //      if(!cmd_buffer->load_state((void *)state_fio)) {
1723 //              return false;
1724 //      }
1725 //      active_cmd = state_fio->FgetInt32();
1726 //      dpp_data = state_fio->FgetUint8();
1727 //      dpp_ctrl = state_fio->FgetUint8();
1728 //      scroll_x0 = state_fio->FgetInt32();
1729 //      scroll_y0 = state_fio->FgetInt32();
1730 //      scroll_x1 = state_fio->FgetInt32();
1731 //      scroll_y1 = state_fio->FgetInt32();
1732 //      cursor_x = state_fio->FgetInt32();
1733 //      cursor_y = state_fio->FgetInt32();
1734 //      read_x = state_fio->FgetInt32();
1735 //      read_y = state_fio->FgetInt32();
1736 //      mode1 = state_fio->FgetUint8();
1737 //      mode2 = state_fio->FgetUint8();
1738 //      mode3 = state_fio->FgetUint8();
1739 //      report = state_fio->FgetUint32();
1740 //      write_cr = state_fio->FgetBool();
1741 //      state_fio->Fread(cvram, sizeof(cvram), 1);
1742 //      state_fio->Fread(gvram, sizeof(gvram), 1);
1743 //      window_x0 = state_fio->FgetInt32();
1744 //      window_y0 = state_fio->FgetInt32();
1745 //      window_x1 = state_fio->FgetInt32();
1746 //      window_y1 = state_fio->FgetInt32();
1747 //      view_x0 = state_fio->FgetInt32();
1748 //      view_y0 = state_fio->FgetInt32();
1749 //      view_x1 = state_fio->FgetInt32();
1750 //      view_y1 = state_fio->FgetInt32();
1751 //      expand = state_fio->FgetDouble();
1752 //      rotate = state_fio->FgetInt32();
1753 //      translate_x = state_fio->FgetInt32();
1754 //      translate_y = state_fio->FgetInt32();
1755 //      point_x = state_fio->FgetInt32();
1756 //      point_y = state_fio->FgetInt32();
1757 //      fore_color = state_fio->FgetInt32();
1758 //      back_color = state_fio->FgetInt32();
1759 //      erase = state_fio->FgetBool();
1760 //      texture = state_fio->FgetInt32();
1761 //      texture_index = state_fio->FgetInt32();
1762 //      pattern = state_fio->FgetInt32();
1763 //      state_fio->Fread(palette_graph, sizeof(palette_graph), 1);
1764 //      blink = state_fio->FgetInt32();
1765         return true;
1766 }
1767
1768 bool DISPLAY::process_state(FILEIO* state_fio, bool loading)
1769 {
1770         if(!state_fio->StateCheckUint32(STATE_VERSION)) {
1771                 return false;
1772         }
1773         if(!state_fio->StateCheckInt32(this_device_id)) {
1774                 return false;
1775         }
1776         if(!cmd_buffer->process_state((void *)state_fio, loading)) {
1777                 return false;
1778         }
1779         state_fio->StateInt32(active_cmd);
1780         state_fio->StateUint8(dpp_data);
1781         state_fio->StateUint8(dpp_ctrl);
1782         state_fio->StateInt32(scroll_x0);
1783         state_fio->StateInt32(scroll_y0);
1784         state_fio->StateInt32(scroll_x1);
1785         state_fio->StateInt32(scroll_y1);
1786         state_fio->StateInt32(cursor_x);
1787         state_fio->StateInt32(cursor_y);
1788         state_fio->StateInt32(read_x);
1789         state_fio->StateInt32(read_y);
1790         state_fio->StateUint8(mode1);
1791         state_fio->StateUint8(mode2);
1792         state_fio->StateUint8(mode3);
1793         state_fio->StateUint32(report);
1794         state_fio->StateBool(write_cr);
1795         state_fio->StateBuffer(cvram, sizeof(cvram), 1);
1796         state_fio->StateBuffer(gvram, sizeof(gvram), 1);
1797         state_fio->StateInt32(window_x0);
1798         state_fio->StateInt32(window_y0);
1799         state_fio->StateInt32(window_x1);
1800         state_fio->StateInt32(window_y1);
1801         state_fio->StateInt32(view_x0);
1802         state_fio->StateInt32(view_y0);
1803         state_fio->StateInt32(view_x1);
1804         state_fio->StateInt32(view_y1);
1805         state_fio->StateDouble(expand);
1806         state_fio->StateInt32(rotate);
1807         state_fio->StateInt32(translate_x);
1808         state_fio->StateInt32(translate_y);
1809         state_fio->StateInt32(point_x);
1810         state_fio->StateInt32(point_y);
1811         state_fio->StateInt32(fore_color);
1812         state_fio->StateInt32(back_color);
1813         state_fio->StateBool(erase);
1814         state_fio->StateInt32(texture);
1815         state_fio->StateInt32(texture_index);
1816         state_fio->StateInt32(pattern);
1817         state_fio->StateBuffer(palette_graph, sizeof(palette_graph), 1);
1818         state_fio->StateInt32(blink);
1819         return true;
1820 }