2 CASIO FP-200 Emulator 'eFP-200'
4 Author : Takeda.Toshiya
11 #include "../datarec.h"
14 #define EVENT_CMT_READY 0
15 #define EVENT_CMT_CLOCK 1
17 #define CMT_MODE_REC 1
18 #define CMT_MODE_PLAY 3
20 #define CMT_RECORDING (cmt_selected && cmt_mode == CMT_MODE_REC && cmt_rec)
21 #define CMT_PLAYING (cmt_selected && cmt_mode == CMT_MODE_PLAY)
23 #define CMT_SAMPLE_RATE 48000
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,
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}
170 void IO::initialize()
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);
177 memcpy(font, elisa_font, sizeof(font));
183 cmt_fio = new FILEIO();
184 cmt_rec = cmt_is_wav = false;
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));
196 b16_1.in_s = b16_1.in_r = true;
197 b16_2.in_s = b16_2.in_r = 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
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);
209 key_stat = emu->get_key_buffer();
220 mode_basic = (config.boot_mode == 0);
222 memset(lcd, 0, sizeof(lcd));
223 lcd[0].cursor = lcd[1].cursor = -1;
224 lcd_status = lcd_addr = 0;
228 cmt_selected = false;
230 cmt_play_ready = cmt_play_signal = cmt_rec_ready = false;
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)
238 void IO::write_io8(uint32_t addr, uint32_t data)
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);
245 switch(addr & 0xff) {
248 if(lcd_status == 0xb0) {
251 } else if(data == 0x50) {
252 lcd[addr & 1].offset = lcd_addr & 0x3ff;
256 } else if(lcd_status == 0x10) {
258 for(int l = 0; l < 8; l++) {
259 lcd[addr & 1].ram[(lcd_addr + 16 * l) & 0x3ff] = REVERSE(font[data * 8 + l]);
262 lcd[addr & 1].ram[lcd_addr & 0x3ff] = data;
267 if((lcd_status = data & 0xf0) == 0xb0) {
268 lcd_addr = (lcd_addr & 0xff) | (data << 8);
272 lcd_addr = (lcd_addr & 0xff00) | data;
275 cmt_selected = ((data & 2) == 0);
276 d_drec->write_signal(SIG_DATAREC_REMOTE, CMT_MODE_PLAY ? 1 : 0, 1);
279 key_column = data & 0x0f;
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);
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);
301 d_drec->write_signal(SIG_DATAREC_REMOTE, CMT_MODE_PLAY ? 1 : 0, 1);
305 switch(addr & 0xf0) {
307 d_rtc->write_io8(addr, data);
313 uint32_t IO::read_io8(uint32_t addr)
315 uint32_t value = 0xff;
318 switch(addr & 0xff) {
321 value = lcd[addr & 1].ram[lcd_addr & 0x3ff];
324 value = ((lcd_addr >> 8) & 0x0f) | lcd_status;
327 value = lcd_addr & 0xff;
334 if(key_column < 10) {
335 for(int i = 0; i < 8; i++) {
336 if(key_stat[key_table[key_column][i]]) {
344 value = (CMT_PLAYING && cmt_play_signal) ? 0x08 : 0;
347 value = ((CMT_PLAYING && cmt_play_ready) || (CMT_RECORDING && cmt_rec_ready)) ? 0x10 : 0;
348 cmt_play_ready = cmt_rec_ready = false;
352 switch(addr & 0xf0) {
354 value = d_rtc->read_io8(addr);
357 value = 0; // no floppy drives
362 this->out_debug_log(_T("%06x\tSOD=%d\tIN8\t%04x = %02x\n"), get_cpu_pc(0), sod ? 1 : 0, addr & 0xff, value);
367 void IO::write_io8w(uint32_t addr, uint32_t data, int* wait)
370 write_io8(addr, data);
373 uint32_t IO::read_io8w(uint32_t addr, int* wait)
376 return read_io8(addr);
379 void IO::write_signal(int id, uint32_t data, uint32_t mask)
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);
389 #define BIT_2400HZ 0x10
390 #define BIT_1200HZ 0x20
391 #define BIT_300HZ 0x80
393 void IO::event_callback(int event_id, int err)
395 if(event_id == EVENT_CMT_READY) {
398 request_skip_frames();
400 cmt_rec_ready = true;
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);
407 b16_1.in_ck = b16_2.in_ck = g21_2.in_ck = false;
408 f21.in_ck = !(g21_1.in_d && false);
410 b16_1.in_ck = b16_2.in_ck = g21_2.in_ck = true;
411 f21.in_ck = !(g21_1.in_d && true);
418 void IO::key_down(int code)
420 if(code >= 0x10 && code <= 0x13) {
423 d_cpu->write_signal(SIG_I8085_RST7, 1, 1);
432 void IO::update_sid()
436 d_cpu->write_signal(SIG_I8085_SID, mode_basic ? 1 : 0, 1);
439 d_cpu->write_signal(SIG_I8085_SID, key_stat[0x10] ? 0 : 1, 1); // shift
442 d_cpu->write_signal(SIG_I8085_SID, key_stat[0x13] ? 0 : 1, 1); // break
445 d_cpu->write_signal(SIG_I8085_SID, key_stat[0x12] ? 0 : 1, 1); // graph
448 d_cpu->write_signal(SIG_I8085_SID, key_stat[0x11] ? 0 : 1, 1); // ctrl
451 d_cpu->write_signal(SIG_I8085_SID, 1, 1);
456 void IO::cmt_write_buffer(uint8_t value, int samples)
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);
467 value = (value > 128) ? 0x80 : 0;
469 int s = min(samples, 0x7f);
471 cmt_buffer[cmt_bufcnt++] = value | s;
472 if(cmt_bufcnt == sizeof(cmt_buffer)) {
473 cmt_fio->Fwrite(cmt_buffer, sizeof(cmt_buffer), 1);
480 void IO::rec_tape(const _TCHAR* file_path)
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);
495 void IO::close_tape()
498 if(cmt_fio->IsOpened()) {
501 cmt_fio->Fwrite(cmt_buffer, cmt_bufcnt, 1);
504 uint32_t length = cmt_fio->Ftell();
506 wav_header_t wav_header;
507 wav_chunk_t wav_chunk;
509 pair_t __riff_chunk_size;
510 pair_t __fmt_chunk_size;
511 pair_t __wav_chunk_size;
514 pair_t __sample_rate;
515 pair16_t __block_size;
516 pair16_t __sample_bits;
518 __riff_chunk_size.d = length - 8;
519 __fmt_chunk_size.d = 16;
522 __sample_rate.d = CMT_SAMPLE_RATE;
526 memcpy(wav_header.riff_chunk.id, "RIFF", 4);
527 wav_header.riff_chunk.size = __riff_chunk_size.get_4bytes_le_to();
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();
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();
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);
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);
557 cmt_rec = cmt_is_wav = false;
561 void IO::update_cmt()
563 bool prev_load_clock = c15.out_y;
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;
585 if(!prev_load_clock && c15.out_y) {
586 cmt_play_ready = true;
587 cmt_play_signal = c15.in_a;
591 void IO::draw_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];
600 uint8_t* d = &screen[y * 8 + l][x * 8];
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];
621 for(int x = 0; x < 160; x++) {
622 dst[x] = src[x] ? cd : cb;
627 #define STATE_VERSION 2
629 void IO::save_state(FILEIO* state_fio)
631 state_fio->FputUint32(STATE_VERSION);
632 state_fio->FputInt32(this_device_id);
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;
658 state_fio->FputInt32(0);
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);
673 bool IO::load_state(FILEIO* state_fio)
677 if(state_fio->FgetUint32() != STATE_VERSION) {
680 if(state_fio->FgetInt32() != this_device_id) {
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();
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);
705 length_tmp -= length_rw;
708 cmt_bufcnt = state_fio->FgetInt32();
710 state_fio->Fread(cmt_buffer, cmt_bufcnt, 1);
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();