OSDN Git Service

[General] Merge Upstream 2017-08-10.
[csp-qt/common_source_project-fm7.git] / source / src / vm / tk80bs / tk80bs.h
1 /*
2         NEC TK-80BS (COMPO BS/80) Emulator 'eTK-80BS'
3         NEC TK-80 Emulator 'eTK-80'
4         NEC TK-85 Emulator 'eTK-85'
5
6         Author : Takeda.Toshiya
7         Date   : 2008.08.26 -
8
9         [ virtual machine ]
10 */
11
12 #ifndef _TK80BS_H_
13 #define _TK80BS_H_
14
15 #if defined(_TK80BS)
16 #define DEVICE_NAME             "NEC TK-80BS"
17 #define CONFIG_NAME             "tk80bs"
18 #elif defined(_TK80)
19 #define DEVICE_NAME             "NEC TK-80"
20 #define CONFIG_NAME             "tk80"
21 #elif defined(_TK85)
22 #define DEVICE_NAME             "NEC TK-85"
23 #define CONFIG_NAME             "tk85"
24 #endif
25
26 // device informations for virtual machine
27 #if defined(_TK80BS)
28 #define FRAMES_PER_SEC          59.9
29 #define LINES_PER_FRAME         262
30 #elif defined(_TK80) || defined(_TK85)
31 #define FRAMES_PER_SEC          30
32 #define LINES_PER_FRAME         256
33 #endif
34 #if defined(_TK80BS) || defined(_TK80)
35 #define CPU_CLOCKS              2048000
36 #define SCREEN_WIDTH            784
37 #define SCREEN_HEIGHT           428
38 #define HAS_I8080
39 #elif defined(_TK85)
40 #define CPU_CLOCKS              2457600
41 #define SCREEN_WIDTH            784
42 #define SCREEN_HEIGHT           534
43 #define HAS_I8085
44 #endif
45 #define I8255_AUTO_HAND_SHAKE
46
47 #define MEMORY_ADDR_MAX         0x10000
48 #define MEMORY_BANK_SIZE        0x200
49 #define IO_ADDR_MAX             0x10000
50
51 // device informations for win32
52 #define ONE_BOARD_MICRO_COMPUTER
53 #if defined(_TK80BS) || defined(_TK80)
54 #define MAX_BUTTONS             25
55 #elif defined(_TK85)
56 #define MAX_BUTTONS             26
57 #endif
58 #if defined(_TK80) || defined(_TK85)
59 #define MAX_DRAW_RANGES         8
60 #endif
61 #if defined(_TK80BS)
62 #define USE_BOOT_MODE           2
63 #endif
64 #define USE_DIPSWITCH
65 #define DIPSWITCH_DEFAULT       0
66 #define USE_TAPE1
67 #if defined(_TK80BS)
68 #define USE_TAPE2
69 #endif
70
71 #define USE_BINARY_FILE1
72 #define NOTIFY_KEY_DOWN
73 #define USE_KEY_LOCKED
74 #define USE_ALT_F10_KEY
75 #define USE_AUTO_KEY            5
76 #define USE_AUTO_KEY_RELEASE    6
77 #define USE_AUTO_KEY_NO_CAPS
78 #define USE_AUTO_KEY_NUMPAD
79 #define USE_SOUND_VOLUME        4
80 #define USE_DEBUGGER
81 #define USE_STATE
82
83 #include "../../common.h"
84 #include "../../fileio.h"
85
86 #ifdef USE_SOUND_VOLUME
87 static const _TCHAR *sound_device_caption[] = {
88         _T("Beep #1"), _T("Beep #2"), _T("CMT (Signal)"), _T("Noise (CMT)"),
89 };
90 #endif
91
92 #if defined(_TK80BS) || defined(_TK80)
93 #define BUTTON_SPACE_X  46
94 #define BUTTON_SPACE_Y  46
95 #define BUTTON_SIZE_X   40
96 #define BUTTON_SIZE_Y   40
97 #define BUTTON_POS_X1   523
98 #define BUTTON_POS_X2   (BUTTON_POS_X1 + BUTTON_SPACE_X * 4)
99 #define BUTTON_POS_Y1   374
100 #define BUTTON_POS_Y2   190
101
102 #define LED_SPACE_X     36
103 #define LED_SIZE_X      33
104 #define LED_SIZE_Y      46
105 #define LED_POS_X1      461
106 #define LED_POS_X2      618
107 #define LED_POS_Y       28
108 #else
109 #define BUTTON_SPACE_X  47
110 #define BUTTON_SPACE_Y  47
111 #define BUTTON_SIZE_X   44
112 #define BUTTON_SIZE_Y   44
113 #define BUTTON_POS_X1   536
114 #define BUTTON_POS_X2   729
115 #define BUTTON_POS_Y1   488
116 #define BUTTON_POS_Y2   296
117
118 #define LED_SPACE_X     39
119 #define LED_SIZE_X      29
120 #define LED_SIZE_Y      39
121 #define LED_POS_X1      446
122 #define LED_POS_X2      607
123 #define LED_POS_Y       130
124 #endif
125
126 const struct {
127         int x, y;
128         int width, height;
129         int code;
130 } vm_buttons[] = {
131         // virtual key codes 0x80-0x8f and 0x98-0x9f are not used in pc keyboard
132         {BUTTON_POS_X1 + BUTTON_SPACE_X * 0, BUTTON_POS_Y1 - BUTTON_SPACE_Y * 0, BUTTON_SIZE_X, BUTTON_SIZE_Y, 0x80},   // 0
133         {BUTTON_POS_X1 + BUTTON_SPACE_X * 1, BUTTON_POS_Y1 - BUTTON_SPACE_Y * 0, BUTTON_SIZE_X, BUTTON_SIZE_Y, 0x81},   // 1
134         {BUTTON_POS_X1 + BUTTON_SPACE_X * 2, BUTTON_POS_Y1 - BUTTON_SPACE_Y * 0, BUTTON_SIZE_X, BUTTON_SIZE_Y, 0x82},   // 2
135         {BUTTON_POS_X1 + BUTTON_SPACE_X * 3, BUTTON_POS_Y1 - BUTTON_SPACE_Y * 0, BUTTON_SIZE_X, BUTTON_SIZE_Y, 0x83},   // 3
136         {BUTTON_POS_X1 + BUTTON_SPACE_X * 0, BUTTON_POS_Y1 - BUTTON_SPACE_Y * 1, BUTTON_SIZE_X, BUTTON_SIZE_Y, 0x84},   // 4
137         {BUTTON_POS_X1 + BUTTON_SPACE_X * 1, BUTTON_POS_Y1 - BUTTON_SPACE_Y * 1, BUTTON_SIZE_X, BUTTON_SIZE_Y, 0x85},   // 5
138         {BUTTON_POS_X1 + BUTTON_SPACE_X * 2, BUTTON_POS_Y1 - BUTTON_SPACE_Y * 1, BUTTON_SIZE_X, BUTTON_SIZE_Y, 0x86},   // 6
139         {BUTTON_POS_X1 + BUTTON_SPACE_X * 3, BUTTON_POS_Y1 - BUTTON_SPACE_Y * 1, BUTTON_SIZE_X, BUTTON_SIZE_Y, 0x87},   // 7
140         {BUTTON_POS_X1 + BUTTON_SPACE_X * 0, BUTTON_POS_Y1 - BUTTON_SPACE_Y * 2, BUTTON_SIZE_X, BUTTON_SIZE_Y, 0x88},   // 8
141         {BUTTON_POS_X1 + BUTTON_SPACE_X * 1, BUTTON_POS_Y1 - BUTTON_SPACE_Y * 2, BUTTON_SIZE_X, BUTTON_SIZE_Y, 0x89},   // 9
142         {BUTTON_POS_X1 + BUTTON_SPACE_X * 2, BUTTON_POS_Y1 - BUTTON_SPACE_Y * 2, BUTTON_SIZE_X, BUTTON_SIZE_Y, 0x8a},   // A
143         {BUTTON_POS_X1 + BUTTON_SPACE_X * 3, BUTTON_POS_Y1 - BUTTON_SPACE_Y * 2, BUTTON_SIZE_X, BUTTON_SIZE_Y, 0x8b},   // B
144         {BUTTON_POS_X1 + BUTTON_SPACE_X * 0, BUTTON_POS_Y1 - BUTTON_SPACE_Y * 3, BUTTON_SIZE_X, BUTTON_SIZE_Y, 0x8c},   // C
145         {BUTTON_POS_X1 + BUTTON_SPACE_X * 1, BUTTON_POS_Y1 - BUTTON_SPACE_Y * 3, BUTTON_SIZE_X, BUTTON_SIZE_Y, 0x8d},   // D
146         {BUTTON_POS_X1 + BUTTON_SPACE_X * 2, BUTTON_POS_Y1 - BUTTON_SPACE_Y * 3, BUTTON_SIZE_X, BUTTON_SIZE_Y, 0x8e},   // E
147         {BUTTON_POS_X1 + BUTTON_SPACE_X * 3, BUTTON_POS_Y1 - BUTTON_SPACE_Y * 3, BUTTON_SIZE_X, BUTTON_SIZE_Y, 0x8f},   // F
148         {BUTTON_POS_X1 + BUTTON_SPACE_X * 0, BUTTON_POS_Y2                     , BUTTON_SIZE_X, BUTTON_SIZE_Y, 0x98},   // RET
149         {BUTTON_POS_X1 + BUTTON_SPACE_X * 1, BUTTON_POS_Y2                     , BUTTON_SIZE_X, BUTTON_SIZE_Y, 0x99},   // RUN
150         {BUTTON_POS_X1 + BUTTON_SPACE_X * 2, BUTTON_POS_Y2                     , BUTTON_SIZE_X, BUTTON_SIZE_Y, 0x9a},   // STORE DATA
151         {BUTTON_POS_X1 + BUTTON_SPACE_X * 3, BUTTON_POS_Y2                     , BUTTON_SIZE_X, BUTTON_SIZE_Y, 0x9b},   // LOAD DATA
152 #if defined(_TK80BS) || defined(_TK80)
153         {BUTTON_POS_X2                     , BUTTON_POS_Y2                     , BUTTON_SIZE_X, BUTTON_SIZE_Y, 0x00},   // RESET
154 #elif defined(_TK85)
155         {BUTTON_POS_X2                     , BUTTON_POS_Y2                     , BUTTON_SIZE_X, BUTTON_SIZE_Y, 0x97},   // MON
156 #endif
157         {BUTTON_POS_X2                     , BUTTON_POS_Y1 - BUTTON_SPACE_Y * 3, BUTTON_SIZE_X, BUTTON_SIZE_Y, 0x9c},   // ADRS SET
158         {BUTTON_POS_X2                     , BUTTON_POS_Y1 - BUTTON_SPACE_Y * 2, BUTTON_SIZE_X, BUTTON_SIZE_Y, 0x9d},   // READ INCR
159         {BUTTON_POS_X2                     , BUTTON_POS_Y1 - BUTTON_SPACE_Y * 1, BUTTON_SIZE_X, BUTTON_SIZE_Y, 0x9e},   // READ DECR
160         {BUTTON_POS_X2                     , BUTTON_POS_Y1 - BUTTON_SPACE_Y * 0, BUTTON_SIZE_X, BUTTON_SIZE_Y, 0x9f},   // WRITE INCR
161 #if defined(_TK85)
162         {727                               , 237                               , 29           , 29           , 0x00},   // RESET
163 #endif
164 };
165 const struct {
166         int x, y;
167         int width, height;
168 } vm_ranges[] = {
169         {LED_POS_X1 + LED_SPACE_X * 0, LED_POS_Y, LED_SIZE_X, LED_SIZE_Y}, // 7-seg LEDs
170         {LED_POS_X1 + LED_SPACE_X * 1, LED_POS_Y, LED_SIZE_X, LED_SIZE_Y},
171         {LED_POS_X1 + LED_SPACE_X * 2, LED_POS_Y, LED_SIZE_X, LED_SIZE_Y},
172         {LED_POS_X1 + LED_SPACE_X * 3, LED_POS_Y, LED_SIZE_X, LED_SIZE_Y},
173         {LED_POS_X2 + LED_SPACE_X * 0, LED_POS_Y, LED_SIZE_X, LED_SIZE_Y},
174         {LED_POS_X2 + LED_SPACE_X * 1, LED_POS_Y, LED_SIZE_X, LED_SIZE_Y},
175         {LED_POS_X2 + LED_SPACE_X * 2, LED_POS_Y, LED_SIZE_X, LED_SIZE_Y},
176         {LED_POS_X2 + LED_SPACE_X * 3, LED_POS_Y, LED_SIZE_X, LED_SIZE_Y},
177 #if defined(_TK80BS)
178         {4, 158, 512, 256}, // CRT
179 #endif
180 };
181
182 class EMU;
183 class DEVICE;
184 class EVENT;
185
186 class DATAREC;
187 class I8080;
188 #if defined(_TK80BS)
189 class I8251;
190 class IO;
191 #endif
192 class I8255;
193 //class MEMORY;
194 class PCM1BIT;
195
196 #if defined(_TK80BS)
197 class CMT;
198 #endif
199 class DISPLAY;
200 class KEYBOARD;
201 class MEMBUS;
202
203 class VM
204 {
205 protected:
206         EMU* emu;
207         
208         // devices
209         EVENT* event;
210         
211         DATAREC* drec;
212         I8080* cpu;
213 #if defined(_TK80BS)
214         I8251* sio_b;
215         I8255* pio_b;
216         IO* memio;
217 #endif
218         I8255* pio_t;
219 //      MEMORY* memory;
220         PCM1BIT* pcm0;
221         PCM1BIT* pcm1;
222         
223 #if defined(_TK80BS)
224         CMT* cmt;
225 #endif
226         DISPLAY* display;
227         KEYBOARD* keyboard;
228         MEMBUS* memory;
229         
230         // memory
231         uint8_t mon[0x800];
232         uint8_t ext[0x7000];
233         uint8_t ram[0x5000];    // with TK-M20K
234 #if defined(_TK80BS)
235         uint8_t basic[0x2000];
236         uint8_t bsmon[0x1000];
237         uint8_t vram[0x200];
238         
239         int boot_mode;
240 #endif
241         
242 public:
243         // ----------------------------------------
244         // initialize
245         // ----------------------------------------
246         
247         VM(EMU* parent_emu);
248         ~VM();
249         
250         // ----------------------------------------
251         // for emulation class
252         // ----------------------------------------
253         
254         // drive virtual machine
255         void reset();
256         void run();
257         
258 #ifdef USE_DEBUGGER
259         // debugger
260         DEVICE *get_cpu(int index);
261 #endif
262         
263         // draw screen
264         void draw_screen();
265 #if defined(_TK80BS)
266         int max_draw_ranges();
267 #endif
268         
269         // sound generation
270         void initialize_sound(int rate, int samples);
271         uint16_t* create_sound(int* extra_frames);
272         int get_sound_buffer_ptr();
273 #ifdef USE_SOUND_VOLUME
274         void set_sound_device_volume(int ch, int decibel_l, int decibel_r);
275 #endif
276         
277         // notify key
278         void key_down(int code, bool repeat);
279         void key_up(int code);
280         bool get_caps_locked();
281         bool get_kana_locked();
282         
283         // user interface
284         void load_binary(int drv, const _TCHAR* file_path);
285         void save_binary(int drv, const _TCHAR* file_path);
286         void play_tape(int drv, const _TCHAR* file_path);
287         void rec_tape(int drv, const _TCHAR* file_path);
288         void close_tape(int drv);
289         bool is_tape_inserted(int drv);
290         bool is_tape_playing(int drv);
291         bool is_tape_recording(int drv);
292         int get_tape_position(int drv);
293         const _TCHAR* get_tape_message(int drv);
294         bool is_frame_skippable();
295         
296         void update_config();
297         void save_state(FILEIO* state_fio);
298         bool load_state(FILEIO* state_fio);
299         
300         // ----------------------------------------
301         // for each device
302         // ----------------------------------------
303         
304         // devices
305         DEVICE* get_device(int id);
306         DEVICE* dummy;
307         DEVICE* first_device;
308         DEVICE* last_device;
309         
310 #if defined(_TK80BS)
311         int draw_ranges;
312 #endif
313 };
314
315 #endif