OSDN Git Service

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