OSDN Git Service

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