OSDN Git Service

[COMMON][VM][Qt] Add common wav-loading / saving helper functions to common.cpp .
[csp-qt/common_source_project-fm7.git] / source / src / vm / fp200 / io.cpp
1 /*
2         CASIO FP-200 Emulator 'eFP-200'
3
4         Author : Takeda.Toshiya
5         Date   : 2013.03.21-
6
7         [ io ]
8 */
9
10 #include "io.h"
11 #include "../datarec.h"
12 #include "../i8080.h"
13
14 #define EVENT_CMT_READY 0
15 #define EVENT_CMT_CLOCK 1
16
17 #define CMT_MODE_REC    1
18 #define CMT_MODE_PLAY   3
19
20 #define CMT_RECORDING   (cmt_selected && cmt_mode == CMT_MODE_REC && cmt_rec)
21 #define CMT_PLAYING     (cmt_selected && cmt_mode == CMT_MODE_PLAY)
22
23 #define CMT_SAMPLE_RATE 48000
24
25 // based on elisa font (http://hp.vector.co.jp/authors/VA002310/index.htm
26 static const uint8_t elisa_font[2048] = {
27         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
28         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
29         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
30         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
31         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
32         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
33         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
34         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
35         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
36         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
37         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
38         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
39         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
40         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
41         0x08, 0x04, 0x02, 0x7f, 0x02, 0x04, 0x08, 0x00, 0x08, 0x10, 0x20, 0x7f, 0x20, 0x10, 0x08, 0x00,
42         0x08, 0x1c, 0x2a, 0x49, 0x08, 0x08, 0x08, 0x00, 0x08, 0x08, 0x08, 0x49, 0x2a, 0x1c, 0x08, 0x00,
43         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x08,
44         0x24, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x12, 0x7f, 0x24, 0x24, 0xfe, 0x48, 0x48,
45         0x08, 0x1c, 0x2a, 0x1c, 0x0a, 0x2a, 0x1c, 0x08, 0x61, 0x92, 0x94, 0x68, 0x16, 0x29, 0x49, 0x86,
46         0x30, 0x48, 0x48, 0x32, 0x4a, 0x44, 0x3a, 0x00, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
47         0x03, 0x04, 0x08, 0x08, 0x08, 0x08, 0x04, 0x03, 0xc0, 0x20, 0x10, 0x10, 0x10, 0x10, 0x20, 0xc0,
48         0x08, 0x2a, 0x1c, 0x08, 0x1c, 0x2a, 0x08, 0x00, 0x08, 0x08, 0x08, 0x7f, 0x08, 0x08, 0x08, 0x00,
49         0x00, 0x00, 0x00, 0x00, 0x60, 0x60, 0x20, 0x40, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00,
50         0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x00,
51         0x3c, 0x42, 0x46, 0x5a, 0x62, 0x42, 0x3c, 0x00, 0x08, 0x18, 0x08, 0x08, 0x08, 0x08, 0x1c, 0x00,
52         0x3c, 0x42, 0x02, 0x0c, 0x10, 0x20, 0x7e, 0x00, 0x3c, 0x42, 0x02, 0x3c, 0x02, 0x42, 0x3c, 0x00,
53         0x04, 0x0c, 0x14, 0x24, 0x44, 0x7e, 0x04, 0x00, 0x7e, 0x40, 0x40, 0x7c, 0x02, 0x02, 0x7c, 0x00,
54         0x3c, 0x42, 0x40, 0x7c, 0x42, 0x42, 0x3c, 0x00, 0x7e, 0x02, 0x04, 0x08, 0x10, 0x10, 0x10, 0x00,
55         0x3c, 0x42, 0x42, 0x3c, 0x42, 0x42, 0x3c, 0x00, 0x3c, 0x42, 0x42, 0x3e, 0x02, 0x42, 0x3c, 0x00,
56         0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x08, 0x10,
57         0x03, 0x0c, 0x30, 0xc0, 0x30, 0x0c, 0x03, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x7e, 0x00, 0x00, 0x00,
58         0xc0, 0x30, 0x0c, 0x03, 0x0c, 0x30, 0xc0, 0x00, 0x1c, 0x22, 0x22, 0x04, 0x08, 0x08, 0x00, 0x08,
59         0x1c, 0x22, 0x4d, 0x55, 0x47, 0x5f, 0x20, 0x1e, 0x18, 0x24, 0x42, 0x42, 0x7e, 0x42, 0x42, 0x00,
60         0x7c, 0x42, 0x42, 0x7c, 0x42, 0x42, 0x7c, 0x00, 0x1c, 0x22, 0x40, 0x40, 0x40, 0x22, 0x1c, 0x00,
61         0x78, 0x24, 0x22, 0x22, 0x22, 0x24, 0x78, 0x00, 0x7e, 0x40, 0x40, 0x7c, 0x40, 0x40, 0x7e, 0x00,
62         0x7e, 0x40, 0x40, 0x7c, 0x40, 0x40, 0x40, 0x00, 0x1c, 0x22, 0x40, 0x47, 0x42, 0x26, 0x1a, 0x00,
63         0x42, 0x42, 0x42, 0x7e, 0x42, 0x42, 0x42, 0x00, 0x1c, 0x08, 0x08, 0x08, 0x08, 0x08, 0x1c, 0x00,
64         0x0e, 0x04, 0x04, 0x04, 0x44, 0x44, 0x38, 0x00, 0x42, 0x44, 0x48, 0x50, 0x68, 0x44, 0x42, 0x00,
65         0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x7e, 0x00, 0x41, 0x63, 0x55, 0x49, 0x41, 0x41, 0x41, 0x00,
66         0x42, 0x62, 0x52, 0x4a, 0x46, 0x42, 0x42, 0x00, 0x18, 0x24, 0x42, 0x42, 0x42, 0x24, 0x18, 0x00,
67         0x7c, 0x42, 0x42, 0x7c, 0x40, 0x40, 0x40, 0x00, 0x18, 0x24, 0x42, 0x42, 0x4a, 0x24, 0x1a, 0x00,
68         0x7c, 0x42, 0x42, 0x7c, 0x48, 0x44, 0x42, 0x00, 0x3c, 0x42, 0x40, 0x3c, 0x02, 0x42, 0x3c, 0x00,
69         0x7f, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00,
70         0x41, 0x41, 0x22, 0x22, 0x14, 0x14, 0x08, 0x00, 0x41, 0x49, 0x49, 0x55, 0x55, 0x22, 0x22, 0x00,
71         0x41, 0x22, 0x14, 0x08, 0x14, 0x22, 0x41, 0x00, 0x41, 0x22, 0x14, 0x08, 0x08, 0x08, 0x08, 0x00,
72         0x7e, 0x02, 0x04, 0x08, 0x10, 0x20, 0x7e, 0x00, 0x07, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x07,
73         0x41, 0x22, 0x14, 0x7f, 0x08, 0x7f, 0x08, 0x08, 0xe0, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xe0,
74         0x08, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x00,
75         0x10, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x02, 0x1e, 0x22, 0x1e, 0x00,
76         0x20, 0x20, 0x20, 0x3c, 0x22, 0x22, 0x3c, 0x00, 0x00, 0x00, 0x1c, 0x22, 0x20, 0x22, 0x1c, 0x00,
77         0x02, 0x02, 0x02, 0x1e, 0x22, 0x22, 0x1e, 0x00, 0x00, 0x00, 0x1c, 0x22, 0x3e, 0x20, 0x1e, 0x00,
78         0x0c, 0x12, 0x10, 0x3c, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x1c, 0x22, 0x22, 0x1e, 0x02, 0x3c,
79         0x20, 0x20, 0x3c, 0x22, 0x22, 0x22, 0x22, 0x00, 0x08, 0x00, 0x18, 0x08, 0x08, 0x08, 0x1c, 0x00,
80         0x08, 0x00, 0x18, 0x08, 0x08, 0x08, 0x48, 0x30, 0x20, 0x20, 0x24, 0x28, 0x30, 0x28, 0x24, 0x00,
81         0x18, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x3c, 0x2a, 0x2a, 0x2a, 0x2a, 0x00,
82         0x00, 0x00, 0x3c, 0x22, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0x1c, 0x22, 0x22, 0x22, 0x1c, 0x00,
83         0x00, 0x00, 0x3c, 0x22, 0x22, 0x3c, 0x20, 0x20, 0x00, 0x00, 0x1e, 0x22, 0x22, 0x1e, 0x02, 0x02,
84         0x00, 0x00, 0x2e, 0x30, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0x1e, 0x20, 0x1c, 0x02, 0x3c, 0x00,
85         0x00, 0x10, 0x3c, 0x10, 0x10, 0x10, 0x0c, 0x00, 0x00, 0x00, 0x22, 0x22, 0x22, 0x22, 0x1e, 0x00,
86         0x00, 0x00, 0x22, 0x22, 0x14, 0x14, 0x08, 0x00, 0x00, 0x00, 0x22, 0x2a, 0x2a, 0x14, 0x14, 0x00,
87         0x00, 0x00, 0x22, 0x14, 0x08, 0x14, 0x22, 0x00, 0x00, 0x00, 0x22, 0x22, 0x22, 0x1e, 0x02, 0x3c,
88         0x00, 0x00, 0x3e, 0x04, 0x08, 0x10, 0x3e, 0x00, 0x03, 0x04, 0x04, 0x08, 0x04, 0x04, 0x04, 0x03,
89         0x08, 0x08, 0x08, 0x00, 0x08, 0x08, 0x08, 0x00, 0xc0, 0x20, 0x20, 0x10, 0x20, 0x20, 0x20, 0xc0,
90         0x00, 0x00, 0x30, 0x49, 0x06, 0x00, 0x00, 0x00, 0x1c, 0x22, 0x22, 0x10, 0x08, 0x08, 0x00, 0x08,
91         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
92         0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
93         0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
94         0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
95         0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0,
96         0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,
97         0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc,
98         0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0x08, 0x08, 0x08, 0x08, 0xff, 0x08, 0x08, 0x08,
99         0x08, 0x08, 0x08, 0x08, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x08, 0x08, 0x08,
100         0x08, 0x08, 0x08, 0x08, 0xf8, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0f, 0x08, 0x08, 0x08,
101         0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00,
102         0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
103         0x00, 0x00, 0x00, 0x00, 0x0f, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x08, 0x08, 0x08,
104         0x08, 0x08, 0x08, 0x08, 0x0f, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0xf8, 0x00, 0x00, 0x00,
105         0x00, 0x00, 0x00, 0x07, 0x08, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0xc0, 0x20, 0x10, 0x10, 0x10,
106         0x10, 0x10, 0x08, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x20, 0xc0, 0x00, 0x00, 0x00, 0x00,
107         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xa0, 0x40,
108         0x0f, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xf0,
109         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x20, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00,
110         0x00, 0x7e, 0x02, 0x7e, 0x02, 0x04, 0x08, 0x30, 0x00, 0x00, 0x00, 0x3e, 0x0a, 0x0c, 0x08, 0x10,
111         0x00, 0x00, 0x00, 0x04, 0x08, 0x18, 0x28, 0x08, 0x00, 0x00, 0x00, 0x08, 0x3e, 0x22, 0x02, 0x0c,
112         0x00, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x08, 0x3e, 0x00, 0x00, 0x00, 0x04, 0x3e, 0x0c, 0x14, 0x24,
113         0x00, 0x00, 0x00, 0x10, 0x3e, 0x12, 0x14, 0x10, 0x00, 0x00, 0x00, 0x00, 0x38, 0x08, 0x08, 0x7c,
114         0x00, 0x00, 0x00, 0x3c, 0x04, 0x3c, 0x04, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x52, 0x52, 0x04, 0x18,
115         0x00, 0x00, 0x00, 0x40, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x01, 0x0a, 0x0c, 0x08, 0x08, 0x10,
116         0x00, 0x02, 0x04, 0x08, 0x18, 0x28, 0x48, 0x08, 0x08, 0x08, 0x7e, 0x42, 0x42, 0x02, 0x04, 0x18,
117         0x00, 0x3e, 0x08, 0x08, 0x08, 0x08, 0x08, 0x7f, 0x04, 0x04, 0x7f, 0x04, 0x0c, 0x14, 0x24, 0x44,
118         0x10, 0x10, 0x7e, 0x12, 0x12, 0x22, 0x22, 0x44, 0x10, 0x10, 0x7f, 0x08, 0x7f, 0x08, 0x04, 0x04,
119         0x20, 0x3e, 0x22, 0x42, 0x02, 0x04, 0x04, 0x18, 0x20, 0x20, 0x3f, 0x24, 0x44, 0x04, 0x08, 0x30,
120         0x00, 0x00, 0x7e, 0x02, 0x02, 0x02, 0x02, 0x7e, 0x00, 0x24, 0xff, 0x24, 0x24, 0x04, 0x04, 0x18,
121         0x00, 0x40, 0x20, 0x42, 0x22, 0x04, 0x08, 0x70, 0x00, 0x7e, 0x02, 0x04, 0x08, 0x14, 0x22, 0x41,
122         0x20, 0x20, 0x7e, 0x22, 0x24, 0x28, 0x20, 0x1e, 0x00, 0x41, 0x41, 0x21, 0x02, 0x02, 0x04, 0x18,
123         0x10, 0x1e, 0x12, 0x32, 0x4e, 0x04, 0x08, 0x70, 0x06, 0x38, 0x08, 0x7f, 0x08, 0x08, 0x08, 0x30,
124         0x00, 0x52, 0x52, 0x02, 0x04, 0x04, 0x08, 0x30, 0x3e, 0x00, 0x00, 0x7f, 0x08, 0x08, 0x08, 0x30,
125         0x20, 0x20, 0x20, 0x38, 0x24, 0x22, 0x20, 0x20, 0x04, 0x04, 0x7f, 0x04, 0x04, 0x04, 0x08, 0x30,
126         0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x7e, 0x02, 0x22, 0x14, 0x0c, 0x12, 0x60,
127         0x08, 0x08, 0x7f, 0x01, 0x06, 0x1a, 0x69, 0x08, 0x00, 0x02, 0x02, 0x02, 0x04, 0x04, 0x08, 0x30,
128         0x00, 0x00, 0x24, 0x24, 0x22, 0x42, 0x81, 0x00, 0x00, 0x40, 0x40, 0x7e, 0x40, 0x40, 0x40, 0x3e,
129         0x00, 0x00, 0x7e, 0x02, 0x02, 0x04, 0x08, 0x30, 0x00, 0x00, 0x18, 0x24, 0x42, 0x01, 0x00, 0x00,
130         0x08, 0x08, 0x7f, 0x08, 0x08, 0x2a, 0x49, 0x08, 0x00, 0x7e, 0x02, 0x02, 0x24, 0x18, 0x08, 0x04,
131         0x00, 0x18, 0x06, 0x18, 0x06, 0x00, 0x30, 0x0e, 0x00, 0x08, 0x08, 0x10, 0x10, 0x24, 0x42, 0x7d,
132         0x00, 0x01, 0x01, 0x12, 0x0a, 0x04, 0x0a, 0x30, 0x00, 0x7e, 0x10, 0x10, 0x7f, 0x10, 0x10, 0x1e,
133         0x10, 0x10, 0xff, 0x11, 0x12, 0x14, 0x10, 0x10, 0x00, 0x00, 0x3c, 0x04, 0x04, 0x04, 0x04, 0x7e,
134         0x00, 0x7e, 0x02, 0x02, 0x7e, 0x02, 0x02, 0x7e, 0x00, 0x3c, 0x00, 0x7e, 0x02, 0x02, 0x04, 0x38,
135         0x00, 0x22, 0x22, 0x22, 0x22, 0x02, 0x04, 0x18, 0x00, 0x28, 0x28, 0x28, 0x28, 0x29, 0x2a, 0x4c,
136         0x00, 0x20, 0x20, 0x20, 0x22, 0x22, 0x24, 0x38, 0x00, 0x7e, 0x42, 0x42, 0x42, 0x42, 0x42, 0x7e,
137         0x00, 0x7e, 0x42, 0x42, 0x02, 0x04, 0x08, 0x30, 0x00, 0x40, 0x20, 0x02, 0x02, 0x04, 0x08, 0x70,
138         0xa0, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xa0, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
139         0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x08, 0x08, 0x0f, 0x08, 0x08, 0x0f, 0x08, 0x08,
140         0x08, 0x08, 0xff, 0x08, 0x08, 0xff, 0x08, 0x08, 0x08, 0x08, 0xf8, 0x08, 0x08, 0xf8, 0x08, 0x08,
141         0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff,
142         0xff, 0x7f, 0x3f, 0x1f, 0x0f, 0x07, 0x03, 0x01, 0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80,
143         0x08, 0x1c, 0x3e, 0x7f, 0x7f, 0x1c, 0x3e, 0x00, 0x36, 0x7f, 0x7f, 0x7f, 0x3e, 0x1c, 0x08, 0x00,
144         0x08, 0x1c, 0x3e, 0x7f, 0x3e, 0x1c, 0x08, 0x00, 0x1c, 0x1c, 0x6b, 0x7f, 0x6b, 0x08, 0x1c, 0x00,
145         0x1c, 0x3e, 0x7f, 0x7f, 0x7f, 0x3e, 0x1c, 0x00, 0x1c, 0x22, 0x41, 0x41, 0x41, 0x22, 0x1c, 0x00,
146         0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01,
147         0x81, 0x42, 0x24, 0x18, 0x18, 0x24, 0x42, 0x81, 0x7f, 0x49, 0x49, 0x49, 0x7f, 0x41, 0x41, 0x43,
148         0x20, 0x3e, 0x48, 0xbe, 0x28, 0xff, 0x08, 0x08, 0x3f, 0x21, 0x3f, 0x21, 0x3f, 0x21, 0x41, 0x83,
149         0x7e, 0x42, 0x42, 0x7e, 0x42, 0x42, 0x42, 0x7e, 0x04, 0xee, 0xa4, 0xff, 0xa2, 0xbf, 0xe2, 0x0a,
150         0x18, 0x04, 0x42, 0xbd, 0x14, 0x14, 0x24, 0x4c, 0x24, 0xc4, 0x4e, 0xed, 0x55, 0xe6, 0xc4, 0x58,
151         0x7f, 0x00, 0x7f, 0x08, 0x08, 0x08, 0x08, 0x00, 0x08, 0x7f, 0x08, 0x7f, 0x49, 0x49, 0x4b, 0x08,
152         0xff, 0x80, 0xa4, 0x94, 0x88, 0x94, 0xe0, 0xff, 0xf8, 0xaf, 0xfa, 0xaa, 0xaa, 0xfa, 0x02, 0x06,
153         0x22, 0xf2, 0x2f, 0x72, 0x6a, 0xa2, 0x22, 0x26, 0x08, 0x08, 0x08, 0x08, 0x08, 0x14, 0x22, 0xc1,
154         0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0x00, 0x00, 0x10, 0x08, 0x04, 0x04, 0x00, 0x00,
155 };
156
157 static const uint8_t key_table[10][8] = {
158         {0x00, 0x00, 0x00, 0x00, 0x37, 0x55, 0x4a, 0x4d},
159         {0x00, 0x00, 0x00, 0x00, 0x38, 0x49, 0x4b, 0xbf},
160         {0x00, 0x00, 0x00, 0x00, 0x39, 0x4f, 0x4c, 0xbe},
161         {0x00, 0x00, 0x00, 0x00, 0x30, 0x50, 0xbc, 0xbb},
162         {0x15, 0x2e, 0x24, 0x70, 0x31, 0x51, 0x41, 0x5a},
163         {0x13, 0xdc, 0x27, 0x71, 0x32, 0x57, 0x53, 0x58},
164         {0x20, 0xde, 0x25, 0x72, 0x33, 0x45, 0x44, 0x43},
165         {0xc0, 0xbd, 0x28, 0x73, 0x34, 0x52, 0x46, 0x56},
166         {0xdb, 0xba, 0x26, 0x74, 0x35, 0x54, 0x47, 0x42},
167         {0x0d, 0xdd, 0x14, 0xe2, 0x36, 0x59, 0x48, 0x4e}
168 };
169
170 void IO::initialize()
171 {
172         FILEIO* fio = new FILEIO();
173         if(fio->Fopen(create_local_path(_T("FONT.ROM")), FILEIO_READ_BINARY)) {
174                 fio->Fread(font, sizeof(font), 1);
175                 fio->Fclose();
176         } else {
177                 memcpy(font, elisa_font, sizeof(font));
178         }
179         delete fio;
180         
181         sod = false;
182         
183         cmt_fio = new FILEIO();
184         cmt_rec = cmt_is_wav = false;
185         cmt_bufcnt = 0;
186         
187         memset(&b16_1, 0, sizeof(b16_1));
188         memset(&b16_2, 0, sizeof(b16_2));
189         memset(&g21_1, 0, sizeof(g21_1));
190         memset(&g21_2, 0, sizeof(g21_2));
191         memset(&c15, 0, sizeof(c15));
192         memset(&c16, 0, sizeof(c16));
193         memset(&f21, 0, sizeof(f21));
194         
195         cmt_clock = 0;
196         b16_1.in_s = b16_1.in_r = true;
197         b16_2.in_s = b16_2.in_r = true;
198         g21_1.in_s = true;
199         g21_2.in_s = g21_2.in_r = true;
200         g21_1.in_d = true;      // f21:q5 and f21:q6 are low
201         c15.in_b = true;        // 300baud
202         c15.in_c = false;       // load clock
203         c15.in_s = false;
204         update_cmt();
205         
206         register_event(this, EVENT_CMT_READY, 1000000.0 / 300.0, true, NULL); // 300baud
207         register_event(this, EVENT_CMT_CLOCK, 1000000.0 / 76800.0, true, NULL);
208         
209         key_stat = emu->get_key_buffer();
210 }
211
212 void IO::release()
213 {
214         close_tape();
215         delete cmt_fio;
216 }
217
218 void IO::reset()
219 {
220         mode_basic = (config.boot_mode == 0);
221         
222         memset(lcd, 0, sizeof(lcd));
223         lcd[0].cursor = lcd[1].cursor = -1;
224         lcd_status = lcd_addr = 0;
225         lcd_text = true;
226         
227         close_tape();
228         cmt_selected = false;
229         cmt_mode = 0;
230         cmt_play_ready = cmt_play_signal = cmt_rec_ready = false;
231         
232         key_column = 0;
233         update_sid();
234 }
235
236 #define REVERSE(v) (((v) & 0x80) >> 7) | (((v) & 0x40) >> 5) | (((v) & 0x20) >> 3) | (((v) & 0x10) >> 1) | (((v) & 0x08) << 1) | (((v) & 0x04) << 3) | (((v) & 0x02) << 5) | (((v) & 0x01) << 7)
237
238 void IO::write_io8(uint32_t addr, uint32_t data)
239 {
240 #ifdef _IO_DEBUG_LOG
241         this->out_debug_log(_T("%06x\tSOD=%d\tOUT8\t%04x, %02x\n"), get_cpu_pc(0), sod ? 1 : 0, addr & 0xff, data & 0xff);
242 #endif
243         
244         if(sod) {
245                 switch(addr & 0xff) {
246                 case 0x01:
247                 case 0x02:
248                         if(lcd_status == 0xb0) {
249                                 if(data == 0x40) {
250                                         lcd_text = false;
251                                 } else if(data == 0x50) {
252                                         lcd[addr & 1].offset = lcd_addr & 0x3ff;
253                                 } else {
254                                         lcd_text = true;
255                                 }
256                         } else if(lcd_status == 0x10) {
257                                 if(lcd_text) {
258                                         for(int l = 0; l < 8; l++) {
259                                                 lcd[addr & 1].ram[(lcd_addr + 16 * l) & 0x3ff] = REVERSE(font[data * 8 + l]);
260                                         }
261                                 } else {
262                                         lcd[addr & 1].ram[lcd_addr & 0x3ff] = data;
263                                 }
264                         }
265                         break;
266                 case 0x08:
267                         if((lcd_status = data & 0xf0) == 0xb0) {
268                                 lcd_addr = (lcd_addr & 0xff) | (data << 8);
269                         }
270                         break;
271                 case 0x09:
272                         lcd_addr = (lcd_addr & 0xff00) | data;
273                         break;
274                 case 0x10:
275                         cmt_selected = ((data & 2) == 0);
276                         d_drec->write_signal(SIG_DATAREC_REMOTE, CMT_MODE_PLAY ? 1 : 0, 1);
277                         break;
278                 case 0x21:
279                         key_column = data & 0x0f;
280                         update_sid();
281                         break;
282                 case 0x40:
283                         if(CMT_RECORDING) {
284                                 if(data & 1) {
285                                         // 1: 2.4KHz * 8
286                                         for(int i = 0; i < 8; i++) {
287                                                 cmt_write_buffer(0xff, CMT_SAMPLE_RATE / 2400 / 2);
288                                                 cmt_write_buffer(0x00, CMT_SAMPLE_RATE / 2400 / 2);
289                                         }
290                                 } else {
291                                         // 0: 1.2KHz * 4
292                                         for(int i = 0; i < 4; i++) {
293                                                 cmt_write_buffer(0xff, CMT_SAMPLE_RATE / 1200 / 2);
294                                                 cmt_write_buffer(0x00, CMT_SAMPLE_RATE / 1200 / 2);
295                                         }
296                                 }
297                         }
298                         break;
299                 case 0x43:
300                         cmt_mode = data & 7;
301                         d_drec->write_signal(SIG_DATAREC_REMOTE, CMT_MODE_PLAY ? 1 : 0, 1);
302                         break;
303                 }
304         } else {
305                 switch(addr & 0xf0) {
306                 case 0x10:
307                         d_rtc->write_io8(addr, data);
308                         break;
309                 }
310         }
311 }
312
313 uint32_t IO::read_io8(uint32_t addr)
314 {
315         uint32_t value = 0xff;
316         
317         if(sod) {
318                 switch(addr & 0xff) {
319                 case 0x01:
320                 case 0x02:
321                         value = lcd[addr & 1].ram[lcd_addr & 0x3ff];
322                         break;
323                 case 0x08:
324                         value = ((lcd_addr >> 8) & 0x0f) | lcd_status;
325                         break;
326                 case 0x09:
327                         value = lcd_addr & 0xff;
328                         break;
329                 case 0x10:
330                         value = 0;
331                         break;
332                 case 0x20:
333                         value = 0;
334                         if(key_column < 10) {
335                                 for(int i = 0; i < 8; i++) {
336                                         if(key_stat[key_table[key_column][i]]) {
337                                                 value |= (1 << i);
338                                         }
339                                 }
340                         }
341                         value = value;
342                         break;
343                 case 0x40:
344                         value = (CMT_PLAYING && cmt_play_signal) ? 0x08 : 0;
345                         break;
346                 case 0x41:
347                         value = ((CMT_PLAYING && cmt_play_ready) || (CMT_RECORDING && cmt_rec_ready)) ? 0x10 : 0;
348                         cmt_play_ready = cmt_rec_ready = false;
349                         break;
350                 }
351         } else {
352                 switch(addr & 0xf0) {
353                 case 0x10:
354                         value = d_rtc->read_io8(addr);
355                         break;
356                 case 0x40:
357                         value = 0; // no floppy drives
358                         break;
359                 }
360         }
361 #ifdef _IO_DEBUG_LOG
362         this->out_debug_log(_T("%06x\tSOD=%d\tIN8\t%04x = %02x\n"), get_cpu_pc(0), sod ? 1 : 0, addr & 0xff, value);
363 #endif
364         return value;
365 }
366
367 void IO::write_io8w(uint32_t addr, uint32_t data, int* wait)
368 {
369         *wait = 2;
370         write_io8(addr, data);
371 }
372
373 uint32_t IO::read_io8w(uint32_t addr, int* wait)
374 {
375         *wait = 2;
376         return read_io8(addr);
377 }
378
379 void IO::write_signal(int id, uint32_t data, uint32_t mask)
380 {
381         if(id == SIG_IO_SOD) {
382                 sod = ((data & mask) != 0);
383         } else if(id == SIG_IO_CMT) {
384                 b16_1.in_d = g21_1.in_ck = c16.in_a = ((data & mask) != 0);
385                 update_cmt();
386         }
387 }
388
389 #define BIT_2400HZ      0x10
390 #define BIT_1200HZ      0x20
391 #define BIT_300HZ       0x80
392
393 void IO::event_callback(int event_id, int err)
394 {
395         if(event_id == EVENT_CMT_READY) {
396                 if(CMT_RECORDING) {
397                         if(!cmt_rec_ready) {
398                                 request_skip_frames();
399                         }
400                         cmt_rec_ready = true;
401                 }
402         } else if(event_id == EVENT_CMT_CLOCK) {
403                 c15.in_d4 = c15.in_d5 = ((cmt_clock & BIT_1200HZ) != 0);
404                 c15.in_d6 = c15.in_d7 = ((cmt_clock & BIT_300HZ ) != 0);
405                 
406                 // 76.8KHz: L->H
407                 b16_1.in_ck = b16_2.in_ck = g21_2.in_ck = false;
408                 f21.in_ck = !(g21_1.in_d && false);
409                 update_cmt();
410                 b16_1.in_ck = b16_2.in_ck = g21_2.in_ck = true;
411                 f21.in_ck = !(g21_1.in_d && true);
412                 update_cmt();
413                 
414                 cmt_clock++;
415         }
416 }
417
418 void IO::key_down(int code)
419 {
420         if(code >= 0x10 && code <= 0x13) {
421                 update_sid();
422         } else {
423                 d_cpu->write_signal(SIG_I8085_RST7, 1, 1);
424         }
425 }
426
427 void IO::key_up()
428 {
429         update_sid();
430 }
431
432 void IO::update_sid()
433 {
434         switch(key_column) {
435         case 5:
436                 d_cpu->write_signal(SIG_I8085_SID, mode_basic ? 1 : 0, 1);
437                 break;
438         case 6:
439                 d_cpu->write_signal(SIG_I8085_SID, key_stat[0x10] ? 0 : 1, 1);  // shift
440                 break;
441         case 7:
442                 d_cpu->write_signal(SIG_I8085_SID, key_stat[0x13] ? 0 : 1, 1);  // break
443                 break;
444         case 8:
445                 d_cpu->write_signal(SIG_I8085_SID, key_stat[0x12] ? 0 : 1, 1);  // graph
446                 break;
447         case 9:
448                 d_cpu->write_signal(SIG_I8085_SID, key_stat[0x11] ? 0 : 1, 1);  // ctrl
449                 break;
450         default:
451                 d_cpu->write_signal(SIG_I8085_SID, 1, 1);
452                 break;
453         }
454 }
455
456 void IO::cmt_write_buffer(uint8_t value, int samples)
457 {
458         if(cmt_is_wav) {
459                 for(int i = 0; i < samples; i++) {
460                         cmt_buffer[cmt_bufcnt++] = value;
461                         if(cmt_bufcnt == sizeof(cmt_buffer)) {
462                                 cmt_fio->Fwrite(cmt_buffer, sizeof(cmt_buffer), 1);
463                                 cmt_bufcnt = 0;
464                         }
465                 }
466         } else {
467                 value = (value > 128) ? 0x80 : 0;
468                 while(samples > 0) {
469                         int s = min(samples, 0x7f);
470                         samples -= s;
471                         cmt_buffer[cmt_bufcnt++] = value | s;
472                         if(cmt_bufcnt == sizeof(cmt_buffer)) {
473                                 cmt_fio->Fwrite(cmt_buffer, sizeof(cmt_buffer), 1);
474                                 cmt_bufcnt = 0;
475                         }
476                 }
477         }
478 }
479
480 void IO::rec_tape(const _TCHAR* file_path)
481 {
482         close_tape();
483         
484         if(cmt_fio->Fopen(file_path, FILEIO_READ_WRITE_NEW_BINARY)) {
485                 my_tcscpy_s(cmt_rec_file_path, _MAX_PATH, file_path);
486                 if(check_file_extension(file_path, _T(".wav"))) {
487                         write_dummy_wav_header((void *)cmt_fio);
488                         cmt_is_wav = true;
489                 }
490                 cmt_bufcnt = 0;
491                 cmt_rec = true;
492         }
493 }
494
495 void IO::close_tape()
496 {
497         // close file
498         if(cmt_fio->IsOpened()) {
499                 if(cmt_rec) {
500                         if(cmt_bufcnt) {
501                                 cmt_fio->Fwrite(cmt_buffer, cmt_bufcnt, 1);
502                         }
503                         if(cmt_is_wav) {
504                                 uint32_t length = cmt_fio->Ftell();
505                                 
506                                 wav_header_t wav_header;
507                                 wav_chunk_t wav_chunk;
508 #if 0                           
509                                 pair_t __riff_chunk_size;
510                                 pair_t __fmt_chunk_size;
511                                 pair_t __wav_chunk_size;
512                                 pair16_t __fmt_id;
513                                 pair16_t __channels;
514                                 pair_t __sample_rate;
515                                 pair16_t __block_size;
516                                 pair16_t __sample_bits;
517
518                                 __riff_chunk_size.d = length - 8;
519                                 __fmt_chunk_size.d = 16;
520                                 __fmt_id.w = 1;
521                                 __channels.w = 1;
522                                 __sample_rate.d = CMT_SAMPLE_RATE;
523                                 __block_size.w = 1;
524                                 __sample_bits.w = 8;
525         
526                                 memcpy(wav_header.riff_chunk.id, "RIFF", 4);
527                                 wav_header.riff_chunk.size = __riff_chunk_size.get_4bytes_le_to();
528         
529                                 memcpy(wav_header.wave, "WAVE", 4);
530                                 memcpy(wav_header.fmt_chunk.id, "fmt ", 4);
531                                 wav_header.fmt_chunk.size = __riff_chunk_size.get_4bytes_le_to();
532                                 wav_header.format_id = __fmt_id.get_2bytes_le_to();
533                                 wav_header.channels = __channels.get_2byte_le_to();
534                                 wav_header.sample_rate = __sample_rate.get_4bytes_le_to();
535                                 wav_header.data_speed =  __sample_rate.get_4bytes_le_to();
536                                 wav_header.block_size = __block_size.get_2bytes_le_to();
537                                 wav_header.sample_bits = __sample_bits_get_2bytes_le_to();
538         
539                                 memcpy(wav_chunk.id, "data", 4);
540                                 __wav_chunk_size.d = length - sizeof(wav_header) - sizeof(wav_chunk);
541                                 wav_chunk.size = __wav_chunk_size.get_4bytes_le_to();
542                                 
543                                 cmt_fio->Fseek(0, FILEIO_SEEK_SET);
544                                 cmt_fio->Fwrite(&wav_header, sizeof(wav_header), 1);
545                                 cmt_fio->Fwrite(&wav_chunk, sizeof(wav_chunk), 1);
546 #else
547                                 if(set_wav_header(&wav_header, &wav_chunk, 1, CMT_SAMPLE_RATE, 8, length)) {
548                                         cmt_fio->Fseek(0, FILEIO_SEEK_SET);
549                                         cmt_fio->Fwrite(&wav_header, sizeof(wav_header), 1);
550                                         cmt_fio->Fwrite(&wav_chunk, sizeof(wav_chunk), 1);
551                                 }
552 #endif
553                         }
554                 }
555                 cmt_fio->Fclose();
556         }
557         cmt_rec = cmt_is_wav = false;
558         cmt_bufcnt = 0;
559 }
560
561 void IO::update_cmt()
562 {
563         bool prev_load_clock = c15.out_y;
564         
565         b16_1.update();
566         b16_2.update();
567         f21.update();
568         g21_1.update();
569         g21_2.update();
570         c16.update();
571         
572         b16_2.in_d = b16_1.out_q;
573         f21.in_clr = (b16_1.out_q && b16_2.out_nq);
574         g21_1.in_d = g21_1.in_r = c15.in_d0 = !(f21.out_q5 && f21.out_q6);
575         g21_2.in_d = g21_1.out_q;
576         c16.in_rc1 = c16.in_rc2 = (g21_1.out_q != g21_2.out_q); // xor
577         c15.in_a = (g21_1.out_q && g21_2.out_q);
578         c16.in_b = c16.out_qa;
579         c15.in_d1 = !c16.out_qa;
580         c15.in_d2 = c16.out_qb;
581         c15.in_d3 = c16.out_qc;
582         
583         c15.update();
584         
585         if(!prev_load_clock && c15.out_y) {
586                 cmt_play_ready = true;
587                 cmt_play_signal = c15.in_a;
588         }
589 }
590
591 void IO::draw_screen()
592 {
593         // render screen
594         for(int y = 0; y < 8; y++) {
595                 for(int x = 0; x < 20; x++) {
596                         int addr = y * 0x80 + (x % 10) + lcd[x < 10].offset;
597                         for(int l = 0; l < 8; l++) {
598                                 uint8_t pat = lcd[x < 10].ram[addr & 0x3ff];
599                                 addr += 0x10;
600                                 uint8_t* d = &screen[y * 8 + l][x * 8];
601                                 
602                                 d[0] = pat & 0x01;
603                                 d[1] = pat & 0x02;
604                                 d[2] = pat & 0x04;
605                                 d[3] = pat & 0x08;
606                                 d[4] = pat & 0x10;
607                                 d[5] = pat & 0x20;
608                                 d[6] = pat & 0x40;
609                                 d[7] = pat & 0x80;
610                         }
611                 }
612         }
613         
614         // copy to real screen
615         scrntype_t cd = RGB_COLOR(48, 56, 16);
616         scrntype_t cb = RGB_COLOR(160, 168, 160);
617         for(int y = 0; y < 64; y++) {
618                 scrntype_t* dst = emu->get_screen_buffer(y);
619                 uint8_t* src = screen[y];
620                 
621                 for(int x = 0; x < 160; x++) {
622                         dst[x] = src[x] ? cd : cb;
623                 }
624         }
625 }
626
627 #define STATE_VERSION   2
628
629 void IO::save_state(FILEIO* state_fio)
630 {
631         state_fio->FputUint32(STATE_VERSION);
632         state_fio->FputInt32(this_device_id);
633         
634         state_fio->Fwrite(lcd, sizeof(lcd), 1);
635         state_fio->FputInt32(lcd_status);
636         state_fio->FputInt32(lcd_addr);
637         state_fio->FputBool(lcd_text);
638         state_fio->FputBool(cmt_selected);
639         state_fio->FputUint8(cmt_mode);
640         state_fio->FputBool(cmt_play_ready);
641         state_fio->FputBool(cmt_play_signal);
642         state_fio->FputBool(cmt_rec_ready);
643         state_fio->FputBool(cmt_rec);
644         state_fio->FputBool(cmt_is_wav);
645         state_fio->Fwrite(cmt_rec_file_path, sizeof(cmt_rec_file_path), 1);
646         if(cmt_rec && cmt_fio->IsOpened()) {
647                 int length_tmp = (int)cmt_fio->Ftell();
648                 cmt_fio->Fseek(0, FILEIO_SEEK_SET);
649                 state_fio->FputInt32(length_tmp);
650                 while(length_tmp != 0) {
651                         uint8_t buffer_tmp[1024];
652                         int length_rw = min(length_tmp, (int)sizeof(buffer_tmp));
653                         cmt_fio->Fread(buffer_tmp, length_rw, 1);
654                         state_fio->Fwrite(buffer_tmp, length_rw, 1);
655                         length_tmp -= length_rw;
656                 }
657         } else {
658                 state_fio->FputInt32(0);
659         }
660         state_fio->FputInt32(cmt_bufcnt);
661         state_fio->Fwrite(cmt_buffer, cmt_bufcnt, 1);
662         state_fio->FputUint8(cmt_clock);
663         state_fio->Fwrite(&b16_1, sizeof(b16_1), 1);
664         state_fio->Fwrite(&b16_2, sizeof(b16_2), 1);
665         state_fio->Fwrite(&g21_1, sizeof(g21_1), 1);
666         state_fio->Fwrite(&g21_2, sizeof(g21_2), 1);
667         state_fio->Fwrite(&c15, sizeof(c15), 1);
668         state_fio->Fwrite(&c16, sizeof(c16), 1);
669         state_fio->Fwrite(&f21, sizeof(f21), 1);
670         state_fio->FputUint8(key_column);
671 }
672
673 bool IO::load_state(FILEIO* state_fio)
674 {
675         close_tape();
676         
677         if(state_fio->FgetUint32() != STATE_VERSION) {
678                 return false;
679         }
680         if(state_fio->FgetInt32() != this_device_id) {
681                 return false;
682         }
683         state_fio->Fread(lcd, sizeof(lcd), 1);
684         lcd_status = state_fio->FgetInt32();
685         lcd_addr = state_fio->FgetInt32();
686         lcd_text = state_fio->FgetBool();
687         cmt_selected = state_fio->FgetBool();
688         cmt_mode = state_fio->FgetUint8();
689         cmt_play_ready = state_fio->FgetBool();
690         cmt_play_signal = state_fio->FgetBool();
691         cmt_rec_ready = state_fio->FgetBool();
692         cmt_rec = state_fio->FgetBool();
693         cmt_is_wav = state_fio->FgetBool();
694         state_fio->Fread(cmt_rec_file_path, sizeof(cmt_rec_file_path), 1);
695         int length_tmp = state_fio->FgetInt32();
696         if(cmt_rec) {
697                 cmt_fio->Fopen(cmt_rec_file_path, FILEIO_READ_WRITE_NEW_BINARY);
698                 while(length_tmp != 0) {
699                         uint8_t buffer_tmp[1024];
700                         int length_rw = min(length_tmp, (int)sizeof(buffer_tmp));
701                         state_fio->Fread(buffer_tmp, length_rw, 1);
702                         if(cmt_fio->IsOpened()) {
703                                 cmt_fio->Fwrite(buffer_tmp, length_rw, 1);
704                         }
705                         length_tmp -= length_rw;
706                 }
707         }
708         cmt_bufcnt = state_fio->FgetInt32();
709         if(cmt_bufcnt) {
710                 state_fio->Fread(cmt_buffer, cmt_bufcnt, 1);
711         }
712         cmt_clock = state_fio->FgetUint8();
713         state_fio->Fread(&b16_1, sizeof(b16_1), 1);
714         state_fio->Fread(&b16_2, sizeof(b16_2), 1);
715         state_fio->Fread(&g21_1, sizeof(g21_1), 1);
716         state_fio->Fread(&g21_2, sizeof(g21_2), 1);
717         state_fio->Fread(&c15, sizeof(c15), 1);
718         state_fio->Fread(&c16, sizeof(c16), 1);
719         state_fio->Fread(&f21, sizeof(f21), 1);
720         key_column = state_fio->FgetUint8();
721         return true;
722 }
723