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 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 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 addr, uint32 data)
241 emu->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 IO::read_io8(uint32 addr)
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 emu->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 addr, uint32 data, int* wait)
370 write_io8(addr, data);
373 uint32 IO::read_io8w(uint32 addr, int* wait)
376 return read_io8(addr);
379 void IO::write_signal(int id, uint32 data, uint32 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 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 uint8 dummy[sizeof(wav_header_t) + sizeof(wav_chunk_t)];
488 memset(dummy, 0, sizeof(dummy));
489 cmt_fio->Fwrite(dummy, sizeof(dummy), 1);
497 void IO::close_tape()
500 if(cmt_fio->IsOpened()) {
503 cmt_fio->Fwrite(cmt_buffer, cmt_bufcnt, 1);
506 uint32 length = cmt_fio->Ftell();
508 wav_header_t wav_header;
509 wav_chunk_t wav_chunk;
511 memcpy(wav_header.riff_chunk.id, "RIFF", 4);
512 wav_header.riff_chunk.size = length - 8;
513 memcpy(wav_header.wave, "WAVE", 4);
514 memcpy(wav_header.fmt_chunk.id, "fmt ", 4);
515 wav_header.fmt_chunk.size = 16;
516 wav_header.format_id = 1;
517 wav_header.channels = 1;
518 wav_header.sample_rate = CMT_SAMPLE_RATE;
519 wav_header.data_speed = CMT_SAMPLE_RATE;
520 wav_header.block_size = 1;
521 wav_header.sample_bits = 8;
523 memcpy(wav_chunk.id, "data", 4);
524 wav_chunk.size = length - sizeof(wav_header) - sizeof(wav_chunk);
526 cmt_fio->Fseek(0, FILEIO_SEEK_SET);
527 cmt_fio->Fwrite(&wav_header, sizeof(wav_header), 1);
528 cmt_fio->Fwrite(&wav_chunk, sizeof(wav_chunk), 1);
533 cmt_rec = cmt_is_wav = false;
537 void IO::update_cmt()
539 bool prev_load_clock = c15.out_y;
548 b16_2.in_d = b16_1.out_q;
549 f21.in_clr = (b16_1.out_q && b16_2.out_nq);
550 g21_1.in_d = g21_1.in_r = c15.in_d0 = !(f21.out_q5 && f21.out_q6);
551 g21_2.in_d = g21_1.out_q;
552 c16.in_rc1 = c16.in_rc2 = (g21_1.out_q != g21_2.out_q); // xor
553 c15.in_a = (g21_1.out_q && g21_2.out_q);
554 c16.in_b = c16.out_qa;
555 c15.in_d1 = !c16.out_qa;
556 c15.in_d2 = c16.out_qb;
557 c15.in_d3 = c16.out_qc;
561 if(!prev_load_clock && c15.out_y) {
562 cmt_play_ready = true;
563 cmt_play_signal = c15.in_a;
567 void IO::draw_screen()
570 for(int y = 0; y < 8; y++) {
571 for(int x = 0; x < 20; x++) {
572 int addr = y * 0x80 + (x % 10) + lcd[x < 10].offset;
573 for(int l = 0; l < 8; l++) {
574 uint8 pat = lcd[x < 10].ram[addr & 0x3ff];
576 uint8* d = &screen[y * 8 + l][x * 8];
590 // copy to real screen
591 scrntype cd = RGB_COLOR(48, 56, 16);
592 scrntype cb = RGB_COLOR(160, 168, 160);
593 for(int y = 0; y < 64; y++) {
594 scrntype* dst = emu->get_screen_buffer(y);
595 uint8* src = screen[y];
597 for(int x = 0; x < 160; x++) {
598 dst[x] = src[x] ? cd : cb;
603 #define STATE_VERSION 2
605 void IO::save_state(FILEIO* state_fio)
607 state_fio->FputUint32(STATE_VERSION);
608 state_fio->FputInt32(this_device_id);
610 state_fio->Fwrite(lcd, sizeof(lcd), 1);
611 state_fio->FputInt32(lcd_status);
612 state_fio->FputInt32(lcd_addr);
613 state_fio->FputBool(lcd_text);
614 state_fio->FputBool(cmt_selected);
615 state_fio->FputUint8(cmt_mode);
616 state_fio->FputBool(cmt_play_ready);
617 state_fio->FputBool(cmt_play_signal);
618 state_fio->FputBool(cmt_rec_ready);
619 state_fio->FputBool(cmt_rec);
620 state_fio->FputBool(cmt_is_wav);
621 state_fio->Fwrite(cmt_rec_file_path, sizeof(cmt_rec_file_path), 1);
622 if(cmt_rec && cmt_fio->IsOpened()) {
623 int length_tmp = (int)cmt_fio->Ftell();
624 cmt_fio->Fseek(0, FILEIO_SEEK_SET);
625 state_fio->FputInt32(length_tmp);
626 while(length_tmp != 0) {
627 uint8 buffer_tmp[1024];
628 int length_rw = min(length_tmp, (int)sizeof(buffer_tmp));
629 cmt_fio->Fread(buffer_tmp, length_rw, 1);
630 state_fio->Fwrite(buffer_tmp, length_rw, 1);
631 length_tmp -= length_rw;
634 state_fio->FputInt32(0);
636 state_fio->FputInt32(cmt_bufcnt);
637 state_fio->Fwrite(cmt_buffer, cmt_bufcnt, 1);
638 state_fio->FputUint8(cmt_clock);
639 state_fio->Fwrite(&b16_1, sizeof(b16_1), 1);
640 state_fio->Fwrite(&b16_2, sizeof(b16_2), 1);
641 state_fio->Fwrite(&g21_1, sizeof(g21_1), 1);
642 state_fio->Fwrite(&g21_2, sizeof(g21_2), 1);
643 state_fio->Fwrite(&c15, sizeof(c15), 1);
644 state_fio->Fwrite(&c16, sizeof(c16), 1);
645 state_fio->Fwrite(&f21, sizeof(f21), 1);
646 state_fio->FputUint8(key_column);
649 bool IO::load_state(FILEIO* state_fio)
653 if(state_fio->FgetUint32() != STATE_VERSION) {
656 if(state_fio->FgetInt32() != this_device_id) {
659 state_fio->Fread(lcd, sizeof(lcd), 1);
660 lcd_status = state_fio->FgetInt32();
661 lcd_addr = state_fio->FgetInt32();
662 lcd_text = state_fio->FgetBool();
663 cmt_selected = state_fio->FgetBool();
664 cmt_mode = state_fio->FgetUint8();
665 cmt_play_ready = state_fio->FgetBool();
666 cmt_play_signal = state_fio->FgetBool();
667 cmt_rec_ready = state_fio->FgetBool();
668 cmt_rec = state_fio->FgetBool();
669 cmt_is_wav = state_fio->FgetBool();
670 state_fio->Fread(cmt_rec_file_path, sizeof(cmt_rec_file_path), 1);
671 int length_tmp = state_fio->FgetInt32();
673 cmt_fio->Fopen(cmt_rec_file_path, FILEIO_READ_WRITE_NEW_BINARY);
674 while(length_tmp != 0) {
675 uint8 buffer_tmp[1024];
676 int length_rw = min(length_tmp, (int)sizeof(buffer_tmp));
677 state_fio->Fread(buffer_tmp, length_rw, 1);
678 if(cmt_fio->IsOpened()) {
679 cmt_fio->Fwrite(buffer_tmp, length_rw, 1);
681 length_tmp -= length_rw;
684 cmt_bufcnt = state_fio->FgetInt32();
686 state_fio->Fread(cmt_buffer, cmt_bufcnt, 1);
688 cmt_clock = state_fio->FgetUint8();
689 state_fio->Fread(&b16_1, sizeof(b16_1), 1);
690 state_fio->Fread(&b16_2, sizeof(b16_2), 1);
691 state_fio->Fread(&g21_1, sizeof(g21_1), 1);
692 state_fio->Fread(&g21_2, sizeof(g21_2), 1);
693 state_fio->Fread(&c15, sizeof(c15), 1);
694 state_fio->Fread(&c16, sizeof(c16), 1);
695 state_fio->Fread(&f21, sizeof(f21), 1);
696 key_column = state_fio->FgetUint8();