OSDN Git Service

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